为什么基于寄存器的虚拟机比基于堆栈的虚拟机更好?
为什么基于寄存器的虚拟机比基于堆栈的虚拟机更好?
具体来说,在Parrot VM 的文档中,设计者解释了注册机的好处:
[...]许多高级语言程序由嵌套函数和方法调用组成,有时还使用词法变量来保存中间结果。在非 JIT 设置下,基于堆栈的 VM 会多次弹出并压入相同的操作数,而基于寄存器的 VM 只会分配适量的寄存器并对其进行操作,这可以显着减少操作量和 CPU 时间。
但为什么相同的操作数会被推送多次呢?
Why are register-based virtual machines better than stack-based ones?
Specifically, in the Parrot VM's document, the designer explains the benefits of register machines:
[...] many programs in high-level languages consist of nested function and method calls, sometimes with lexical variables to hold intermediate results. Under non-JIT settings, a stack-based VM will be popping and then pushing the same operands many times, while a register-based VM will simply allocate the right amount of registers and operate on them, which can significantly reduce the amount of operations and CPU time.
but why are the same operands pushed many times?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
他们似乎描述了一个虚拟机,该虚拟机按照语言设计中的描述执行代码,逐个字节码,无需编译或优化。在这种情况下,这是真的。例如,考虑一下执行类似操作的代码:
使用基于寄存器的系统,您可以简单地将参数放在所需的任何位置(如果寄存器可用于传递参数)。如果所有寄存器都是“全局”的,而不是每个函数的(或者至少在弹出调用堆栈时恢复),您可能不需要在调用
first
和second.
如果您有一个基于堆栈的虚拟机,您最终会得到类似的结果(希望您确实有交换):
此外,如果您计算重用相同变量的数学表达式,您可能需要这样做像这样的东西:
而不是(假设有寄存器a,b,c,并且您可以销毁b和c的内容):
这避免了恢复
a
,这需要在单独的推入中完成第一个案例。再说一遍,我只是猜测这些例子,也许它们意味着其他一些情况......
It seems like they describe a VM which executes the code as described in the language design, bytecode-by-bytecode without compiling or optimisation. In that case it is true. Think about code doing something like this for example:
With a register based system, you might be able to simply put the arguments in whatever position they're expected (if registers can be used to pass arguments). If all registers are "global", not per-function (or at least restored when poping the call-stack) you might not need to do anything between the call to
first
andsecond
.If you have a stack-based VM, you'd end up with something like (hopefully you do have
swap
):Also if you calculate a math expression which reuses the same variables, you might need to do something like this:
instead of (assuming there are registers a,b,c and you can destroy the contents of b and c):
this avoids restoring
a
, which needed to be done in a separate push in the first case.Then again, I'm just guessing the examples, maybe they meant some other case...