73

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

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

4

8 回答 8

48

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

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

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

于 2008-10-02T19:43:47.433 回答
42

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

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

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

此外,许多高级语言的程序由嵌套的函数和方法调用组成,有时使用词法变量来保存中间结果。在非 JIT 设置下,基于堆栈的 VM 将多次弹出然后推送相同的操作数,而基于寄存器的 VM 将简单地分配正确数量的寄存器并对其进行操作,这可以显着减少操作量和 CPU 时间。

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

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

于 2008-10-02T21:53:11.553 回答
27

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

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

于 2011-03-11T11:58:53.680 回答
12

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

于 2008-10-02T19:52:11.577 回答
7

你需要多少个寄存器?

我可能还需要至少一个。

于 2008-10-02T19:38:18.880 回答
3

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

于 2008-10-02T20:35:17.667 回答
3

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

于 2008-10-14T22:03:45.033 回答
2

基于堆栈的 VM 更容易为其生成代码。

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

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

于 2008-10-02T20:01:14.723 回答