为什么基于JVM栈和Dalvik VM寄存器?
我很好奇,为什么Sun决定创build基于JVM栈,而Google决定制作基于DalvikVM寄存器的?
我猜想JVM不能真的假定在目标平台上有一定数量的寄存器可用,因为它应该是平台独立的。 因此,它只是推迟寄存器分配等,到JIT编译器。 (如我错了请纠正我。)
所以,Android的人认为,“嘿,这是无效的,让我们立即注册基于VM …”? 但是,等等,有多种不同的Android设备,Dalvik目标有多less个寄存器呢? Dalvik操作码是否针对一定数量的寄存器进行硬编码?
目前市场上所有的Android设备都拥有相同数量的寄存器吗? 或者,是否有在dex-loading期间执行的寄存器重新分配? 这一切如何融合在一起?
基于堆栈的虚拟机具有一些与Java的devise目标相符的属性:
-
基于堆栈的devise对目标硬件(寄存器,CPUfunction)的假设很less,所以很容易在各种硬件上实现VM。
-
由于指令的操作数在很大程度上是隐含的,所以目标代码会变小。 如果您要通过慢速networking链接下载代码,这一点非常重要。
使用基于寄存器的scheme可能意味着Dalvik的代码生成器不必难以生成高性能代码。 运行在一个非常寄存器丰富或者寄存器不多的架构上可能会妨碍Dalvik,但这不是通常的目标 – ARM是一个非常中等的架构。
我也忘记了Dalvik的最初版本根本不包括JIT。 如果你要直接解释说明,那么基于注册的scheme可能是口译performance的赢家。
我找不到参考,但我认为Sun决定采用基于堆栈的字节码方法,因为它使得在几乎没有寄存器的架构(例如IA32)上运行JVM变得容易。
在来自Google I / O 2008的Dalvik VM Internals中 ,Dalvik的创build者Dan Bornstein在演示幻灯片的幻灯片35中为select基于寄存器的VM提供了以下参数:
注册机
为什么?
- 避免指令发送
- 避免不必要的内存访问
- 有效地使用指令stream(每条指令的语义密度更高)
和幻灯片36:
注册机
统计
- 指令减less30%
- 代码单元less了35%
- 指令stream中多了35%的字节
- 但我们一次只能消耗两个
根据Bornstein的说法,这是“将一组类文件转换为dex文件时可以find的一般期望”。
演示video的相关部分从25:00开始 。
我不知道为什么Sun决定使用JVM堆栈。 Erlangs虚拟机,BEAM是基于性能原因的寄存器。 而且由于性能的原因,Dalvik似乎也是基于注册的。
从Pro Android 2 :
Dalvik使用寄存器作为数据存储的主要单位而不是堆栈。 Google希望能够将指令数量减less30%。
而关于代码大小:
Dalvik VM获取生成的Java类文件并将它们组合成一个或多个Dalvik Executables(.dex)文件。 它重复使用来自多个类文件的重复信息,从传统的.jar文件中有效地减less了一半(未压缩)的空间需求。 例如,Android中的Web浏览器应用程序的.dex文件约为200k,而等效的未压缩.jar版本约为500k。 闹钟的.dex文件约为50k,在.jar版本中约为其大小的两倍。
正如我所记得的“ 计算机体系结构:定量方法”也得出结论:注册机比基于堆栈的机器执行得更好。