使用基于寄存器的虚拟机与使用基于堆栈的虚拟机有什么优缺点?
对我而言,似乎基于寄存器的机器可以更直接地编程并且更有效。那么为什么JVM,CLR和Python VM都是基于堆栈的呢?
答案 0 :(得分:38)
在硬件中实现,基于寄存器的机器将更加高效,因为对较慢的RAM的访问较少。然而,在软件中,即使是基于寄存器的架构也很可能在RAM中具有“寄存器”。在这种情况下,基于堆栈的机器将同样有效。
此外,基于堆栈的VM将使编写编译器变得更加容易。您不必处理寄存器分配策略。实际上,您可以使用无限数量的寄存器。
更新:我在假设解释的虚拟机时写了这个答案。它可能不适用于JIT编译的VM。我跑过this paper,这似乎表明使用寄存器架构JIT编译的VM可能更有效。
答案 1 :(得分:31)
在Parrot VM的FAQ和相关文档中,已经在一定程度上回答了这个问题: A Parrot Overview 该文档的相关文本是:
Parrot VM将具有寄存器架构,而不是堆栈架构。它也将具有极低级别的操作,与Java相似,而不是Perl和Python等中级操作。
这个决定的原因主要是通过在某种程度上类似于底层硬件,可以将Parrot字节码编译成高效的本机机器语言。
此外,高级语言中的许多程序都包含嵌套函数和方法调用,有时使用词法变量来保存中间结果。在非JIT设置下,基于堆栈的VM将弹出,然后多次推送相同的操作数,而基于寄存器的VM将简单地分配适当数量的寄存器并对其进行操作,这可以显着减少操作量和CPU时间。
您可能还想阅读此内容:Registers vs stacks for interpreter design 引用它:
毫无疑问,为堆栈计算机生成代码更容易。大多数新生编译学生都可以做到这一点。为寄存器机器生成代码有点困难,除非您将其视为具有累加器的堆栈机器。 (从性能的角度来看,这是可行的,虽然有点不太理想)目标的简单性并不是一件大事,至少对我来说不是这样,部分原因是很少有人真正直接针对它 - 我的意思是,来吧,你知道有多少人真正尝试为任何人都会关心的东西编写编译器?数字很小。另一个问题是,许多拥有编译器知识的人已经习惯于定位注册机,因为这是所有常用的硬件CPU。
答案 2 :(得分:20)
传统上,虚拟机实现者更喜欢基于堆栈的体系结构而不是基于寄存器,因为“VM实现的简单性”易于编写编译器后端 - 大多数VM最初设计用于承载单一语言和代码密度以及可执行文件堆栈体系结构总是小于寄存器体系结构的可执行文件。简单性和代码密度是性能成本。
研究表明,基于注册的体系结构需要比基于堆栈的体系结构平均执行的VM指令少47%,并且寄存器代码比相应的堆栈代码大25%但这增加了获取更多VM指令的成本更大的代码大小仅涉及每个VM指令1.07%的额外实际机器负载,这可以忽略不计。基于寄存器的VM的整体性能平均需要32.3%的时间来执行标准基准测试。
答案 3 :(得分:12)
构建基于堆栈的VM的一个原因是实际的VM操作码可以更小更简单(不需要编码/解码操作数)。这使得生成的代码更小,并且还使VM代码更简单。
答案 4 :(得分:7)
您需要多少个寄存器?
我可能至少还需要一个。
答案 5 :(得分:3)
对我而言,“基于寄存器的”虚拟机“更直接地编程”或“更高效”并不是显而易见的。也许您认为虚拟寄存器会在JIT编译阶段提供快捷方式?这肯定不是这种情况,因为真实处理器可以具有比VM更多或更少的寄存器,并且这些寄存器可以以不同方式使用。 (例如:将要递减的值最好放在x86处理器上的ECX寄存器中。)如果真实机器的寄存器多于VM,那么你浪费的资源就少了,而且你使用“寄存器就没有任何收获基于“编程。
答案 6 :(得分:3)
基于堆栈的VM更简单,代码更紧凑。作为一个真实世界的例子,一位朋友(大约30年前)在Cosmac上构建了一个带有自制Forth VM的数据记录系统。在具有2k ROM和256字节RAM的机器上,Forth VM是30 字节的代码。
答案 7 :(得分:1)
基于堆栈的虚拟机更容易为其生成代码。
基于寄存器的虚拟机更容易为其创建快速实现,并且更容易为其生成高度优化的代码。
对于您的第一次尝试,我建议从基于堆栈的VM开始。