与使用基于堆栈的虚拟机相比,使用基于寄存器的虚拟机到底有哪些优点和缺点?

对我来说,基于寄存器的机器似乎更容易编程并且更高效。那么为什么 JVM、CLR 和 Python VM 都是基于堆栈的呢?

有帮助吗?

解决方案

Parrot VM 的常见问题解答和相关文档中已经在一定程度上回答了这个问题:鹦鹉概述该文档的相关文本是这样的:

Parrot VM 将采用寄存器架构,而不是堆栈架构。它还将具有极低级的操作,与 Perl 和 Python 等的中级操作相比,更类似于 Java。

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

此外,高级语言中的许多程序都包含嵌套的函数和方法调用,有时还使用词法变量来保存中间结果。在非 JIT 设置下,基于堆栈的 VM 会多次弹出并压入相同的操作数,而基于寄存器的 VM 只会分配适量的寄存器并对其进行操作,这可以显着减少操作量和CPU时间。

您可能还想阅读以下内容: 解释器设计中的寄存器与堆栈 稍微引用一​​下:

毫无疑问,为堆栈机生成代码更容易。大多数编译器新生都可以做到这一点。为寄存器机生成代码有点困难,除非您将其视为带有累加器的堆栈机。(这是可行的,尽管从性能的角度来看不太理想)目标的简单性并不是那么重要,至少对我来说不是,部分原因是很少有人真正会直接瞄准它 - 我的意思是,来吧,你知道有多少人真正尝试为任何人都关心的东西编写编译器?数字很​​小。另一个问题是,许多具有编译器知识的人已经习惯了以寄存器机为目标,因为这就是所有常用的硬件 CPU 的用途。

其他提示

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

此外,基于堆栈的VM将使编写编译器变得更加容易。您不必处理寄存器分配策略。实际上,您可以使用无限数量的寄存器。

更新:我在假设解释的虚拟机时写了这个答案。它可能不适用于JIT编译的VM。我遇到了这篇论文,这似乎表明JIT已编译使用寄存器架构VM可能更有效。

传统上,虚拟机实现者更喜欢基于堆栈的架构,而不是基于寄存器的架构,因为“虚拟机实现简单”,易于编写编译器后端 - 大多数虚拟机最初设计为托管单一语言和代码密度以及堆栈架构的可执行文件总是小于寄存器架构的可执行文件。简单性和代码密度是性能成本。

研究表明,基于寄存器的架构比基于堆栈的架构平均需要少执行 47% 的 VM 指令,并且寄存器代码比相应的堆栈代码大 25%,但由于代码较大,这会增加获取更多 VM 指令的成本每个 VM 指令的大小仅涉及​​ 1.07% 的额外实际机器负载,可以忽略不计。基于寄存器的 VM 的整体性能是,执行标准基准测试所需的时间平均减少 32.3%。

构建基于堆栈的VM的一个原因是实际的VM操作码可以更小更简单(不需要编码/解码操作数)。这使得生成的代码更小,并且还使VM代码更简单。

您需要多少个寄存器?

我可能至少还需要一个。

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

基于堆栈的VM更简单,代码更紧凑。作为一个真实世界的例子,一位朋友(大约30年前)在Cosmac上构建了一个带有自制Forth VM的数据记录系统。在具有2k ROM和256字节RAM的机器上,Forth VM是30 字节的代码。

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

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

对于您的第一次尝试,我建议从基于堆栈的VM开始。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top