为什么选择基于堆栈的虚拟机?为什么不基于队列的VM? [英] Why stack-based VM? Why not queue-based VM?

查看:338
本文介绍了为什么选择基于堆栈的虚拟机?为什么不基于队列的VM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如我调查的那样,有两种主要的方法来实现流程虚拟机:

As I investigated, there are 2 major ways to implement process VM:

  • 基于堆栈,例如JVM,CLR等
  • 或基于寄存器的,例如Lua,Dalvik等

基于寄存器的方法模仿物理处理器的体系结构. 但是对于基于堆栈的方法,还有许多其他数据结构.

Register-based approach mimics the architecture of physical processors. But for the stack-based approach, there are many other data structures.

我认为选择哪种方法主要取决于我们要如何存储/获取操作数.那么为什么选择堆栈呢?基于队列的虚拟机怎么样?还是其他选项,例如链表?

I think which approach to choose mainly depends on how we want to store/fetch operands. So why choose stack? How about queue-based VM? Or other options such as linked list?

推荐答案

StackOverflow确实不适用于基于意见的调查.可能会关闭.

StackOverflow is really not for opinion-based surveying; it's likely to be closed.

但是,关键是要认识到特定于处理器的体系结构通常使用寄存器,因为这与处理器的工作方式相对应.每个指令集都有一组固定的可用寄存器,不同的体系结构将具有不同的数量.此外,某些寄存器基于平台或ABI具有特定的含义.

However, it's key to realise that processor-specific architectures generally use registers because that corresponds to how the processors work. Each instruction set has a fixed set of registers available, and different architectures will have different amounts. Furthermore, some registers have specific meanings based on the platform or ABI.

然后,很难在平台之间移植通用程序集文件.或者,如果可以的话,您将获得尽可能少的结果,因此错过了可能适用于更广泛说明的优化. 64位处理器的优点之一不是增加额外的宽度,而是增加了ISA中可用的寄存器数量.

A generic assembly file is then difficult to port between platforms; or if you can, you end up with the minimum possible and therefore miss out optimisations that may be applicable on wider instructions. One of the advantages of 64 bit processors isn't so much the extra width, but rather the increased number of registers available in the ISA.

有两种解决方法:要么假定一个无限的寄存器集,然后在将其转换为特定体系结构时提供寄存器映射(例如LLVM使用其ISA中的无限寄存器集,然后将其映射到实际ISA上的特定寄存器中)或使用堆栈.使用堆栈的一个优点是,用完堆栈时无需处理溢出寄存器的特定情况(例如,您有一个函数希望拥有10个寄存器,但ISA只有5个).堆栈非常擅长表示无限项(当然,以可用内存量为模.)

There are two ways of solving this; either assume an infinite register set, and then provide register mapping when it's translated for a specific architecture (e.g. LLVM uses an infinite register set in its ISA which is then mapped onto specific registers on the real ISA) or use a stack. One advantage of using a stack is that you don't need to deal with the specific case of spilling the registers when you run out (e.g. you have a function which you'd like to have 10 registers but your ISA only has 5). Stacks are very good at representing infinite entries (modulo the amount of available memory, of course.)

也就是说,(真实)堆栈速度较慢-实际上,当您使用它时,您会忽略实际寄存器.因此,通常,寄存器用于提高速度,而堆栈则用于不适合寄存器的内容.

That said, (real) stacks are slower - effectively you're ignoring real registers when you use that. So typically registers are used for speed, and stacks are used for things that don't fit in the registers.

无论如何-VM代码使用堆栈,因为pushpop之类的指令仅处理单个值,而基于寄存器的指令通常在操作码编码中使用位标志来指示要使用N个寄存器中的哪个.因此,定义基于堆栈的ISA可以为您提供完全灵活的无限数据点集,然后解释器/JIT可以根据需要将它们转换为特定的寄存器-实际上,可以执行LLVM在编译时所做的工作以优化运行时.这样一来,在64位系统上运行的Java程序就可以自动从较大的寄存器集中选取,而无需重新编译即可在32位系统上运行-您会自动获得较宽的寄存器集.

Anyway - the VM codes use a stack because instructions like push and pop only deal with single values, whereas register based instructions typically use bitflags in the opcode encoding to indicate which of the N registers to use. So defining a stack based ISA gives you a fully flexible infinite set of data points, and the interpreter/JIT can then translate those to specific registers on demand - in effect, doing what LLVM does at compile time to run-time optimisations. This allows Java programs running on 64 bit systems automatically able to pick up on the larger register set without needing a recompilation from running on 32 bit - and you get the wider registers set automatically.

此处的堆栈"是一个逻辑概念,而不是特定的数据结构.使用非连续的非增长数据结构实际上没有任何意义.堆栈是专门使用的,因为通常调用新的子例程/函数/方法会生成一个新的堆栈"空间,因此,在从封闭方法返回之前,您总是从该子例程返回,因此只能弹出/推入一端(例如,队列与此处无关).除其他外,这就是为什么您会获得StackOverflow异常的原因,以及为什么将此站点称为StackOverflow而不是QueueOverflow的原因.

The 'stack' here is a logical concept rather than a particular data structure. It wouldn't really make sense to use non-contiguous non-growing data structures. And stacks are used specifically because typically calling a new subroutine/function/method generates a new 'stack' space, so you always return from that subroutine before you return from the enclosing method, so you only ever pop/push one end (e.g. a queue isn't relevant here). Amongst other things, that's why you get StackOverflow exceptions and why this site is called StackOverflow and not QueueOverflow.

这篇关于为什么选择基于堆栈的虚拟机?为什么不基于队列的VM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆