Language agnostic 为什么基于寄存器的虚拟机优于基于堆栈的虚拟机?

Language agnostic 为什么基于寄存器的虚拟机优于基于堆栈的虚拟机?,language-agnostic,vm-implementation,stack-based,Language Agnostic,Vm Implementation,Stack Based,为什么基于寄存器的虚拟机优于基于堆栈的虚拟机 具体而言,在中,设计师解释了注册机的好处: […]高级语言中的许多程序都由嵌套的函数和方法调用组成,有时使用词法变量来保存中间结果。在非JIT设置下,基于堆栈的VM将弹出并多次推送相同的操作数,而基于寄存器的VM只需分配适当数量的寄存器并对其进行操作,这可以显著减少操作量和CPU时间 但是为什么要多次推送相同的操作数?它们似乎描述了一个VM,它按照语言设计中的描述执行代码,一个字节码一个字节码地执行,而无需编译或优化。在这种情况下,这是真的。考虑代码

为什么基于寄存器的虚拟机优于基于堆栈的虚拟机

具体而言,在中,设计师解释了注册机的好处:

[…]高级语言中的许多程序都由嵌套的函数和方法调用组成,有时使用词法变量来保存中间结果。在非JIT设置下,基于堆栈的VM将弹出并多次推送相同的操作数,而基于寄存器的VM只需分配适当数量的寄存器并对其进行操作,这可以显著减少操作量和CPU时间


但是为什么要多次推送相同的操作数?

它们似乎描述了一个VM,它按照语言设计中的描述执行代码,一个字节码一个字节码地执行,而无需编译或优化。在这种情况下,这是真的。考虑代码执行如下操作,例如:

x = first(a,b,c)
y = second(a,b,c)
third(y,x)
使用基于寄存器的系统,您可以简单地将参数放在期望的任何位置(如果可以使用寄存器传递参数)。如果所有寄存器都是“全局”的,而不是每个函数(或者至少在弹出调用堆栈时恢复),则在调用
第一个
第二个
之间可能不需要执行任何操作

如果你有一个基于堆栈的虚拟机,你最终会得到类似的东西(希望你有
swap
):

此外,如果计算重用相同变量的数学表达式,则可能需要执行以下操作:

push a
push b
add
push a
push c
add
add
而不是(假设存在寄存器a、b、c,并且您可以销毁b和c的内容):

这样可以避免还原
a
,而在第一种情况下,这需要在单独的推送中完成

再说一遍,我只是在猜测这些例子,也许它们是指其他情况…

可能的重复
push a
push b
add
push a
push c
add
add
add b, a
add c, a
add b, c # result in b