注册vs堆栈

使用基于寄存器的虚拟机与使用基于堆栈的虚拟机相比有什么优势和劣势?

对我来说,似乎基于寄存器的机器会更直接地编程和更高效。 那么为什么JVM,CLR和Python VM都是基于堆栈的呢?

这已经在Parrot VM的FAQ和相关文档中得到了一定程度的回答: 鹦鹉概述该文档的相关文本是这样的:

鹦鹉VM将有一个寄存器架构,而不是一个堆栈架构。 它也会有非常低级的操作,比起Perl和Python等的中级操作更类似于Java。

这个决定的原因主要是通过在某种程度上类似于底层硬件,可以将Parrot字节码编译为高效的本地机器语言。

而且,许多高级语言的程序都是嵌套的函数和方法调用,有时还有词法variables来保存中间结果。 在非JIT设置下,基于堆栈的虚拟机会popup,然后多次推送相同的操作数,而基于寄存器的虚拟机将简单地分配适量的寄存器并对其进行操作,这可以显着减less操作的数量和CPU时间。

你也可以阅读这个: 解释器devise的寄存器vs堆栈引用它:

毫无疑问,为堆栈机器生成代码更容易。 大多数新生编译的学生可以做到这一点。 为注册机器生成代码有点困难,除非你把它作为一个带有累加器的堆栈机器来处理。 (从性能的angular度来看,这是可行的,尽pipe有点不太理想)简单的瞄准并不是什么大问题,至less对于我来说并不是那么重要,部分原因是很less有人真正直接瞄准它 – 我的意思是,来吧,有多less人知道谁真正试图编写一个任何人都会关心的编译器? 数字很​​小。 另一个问题是,许多具有编译器知识的人已经是舒适的定位寄存器机器,因为这是常用的所有硬件CPU。

在硬件中实现,基于寄存器的机器将会更加高效,因为对较慢的RAM的访问更less。 然而,在软件中,即使是基于寄存器的架构也很可能在RAM中具有“寄存器”。 在这种情况下,基于堆栈的机器将会同样高效。

此外,基于堆栈的虚拟机将使编写编译器变得更加容易。 您不必处理寄存器分配策略。 本质上,您拥有无限数量的寄存器可供使用。

更新:我写了这个答案,假设解释的虚拟机。 它可能不适用于JIT编译的虚拟机。 我碰到这篇文章 ,这似乎表明,使用寄存器体系结构,JIT编译的虚拟机可能更有效。

传统上,虚拟机实现者基于基于寄存器的架构偏爱基于寄存器的架构,这是由于“虚拟机实现的简单性”易于编写后端编译器 – 大多数虚拟机最初被devise为承载单一语言,代码密度和可执行的堆栈体系结构总是比寄存器体系结构的可执行文件小。 简单性和代码密度是性能的代价。

研究表明,基于注册的体系结构要求比基于堆栈的体系结构平均less执行VM指令47%,并且寄存器代码比相应的堆栈代码大25%,但是由于代码较大,这会增加获取更多VM指令的成本大小只涉及每个虚拟机指令的1.07%多余的实际机器负载,这是微不足道的。 基于寄存器的虚拟机的总体性能是平均执行标准基准的时间减less32.3%。

构build基于栈的虚拟机的一个原因是,实际的虚拟机操作码可以更小,更简单(不需要编码/解码操作数)。 这使生成的代码更小,也使得VM代码更简单。

你需要多less个寄存器?

我可能至less需要一个以上。

对我来说,“基于寄存器的”虚拟机“更直接地编程”或“更高效”是不明显的。 也许你认为虚拟寄存器会在JIT编译阶段提供一个捷径? 这肯定不是这种情况,因为真实的处理器可能比VM有更多或更less的寄存器,并且这些寄存器可能以不同的方式使用。 (例如:要减less的值最好放在x86处理器的ECX寄存器中。)如果真机的寄存器数量多于虚拟机,那么就浪费了资源,减less了使用“寄存器基于“的编程。

基于栈的虚拟机比较简单,代码更加紧凑。 作为一个真实世界的例子,一个朋友(大约30年前)在Cosmac上build立了一个带有自制Forth VM的数据logging系统。 第二台虚拟机在一台机器上有30 个字节的代码,有2K的ROM和256字节的RAM。

基于堆栈的虚拟机更容易生成代码。

基于寄存器的虚拟机更容易创build快速实现,并更容易生成高度优化的代码。

为了您的第一次尝试,我build议从基于堆栈的虚拟机开始。