为什么JVM是基于堆栈的,而Dalvik VM是基于寄存器的?

xzabzqsa  于 5个月前  发布在  其他
关注(0)|答案(3)|浏览(76)

我很好奇,为什么Sun决定让JVM基于堆栈,而Google决定让DalvikVM基于寄存器?
我认为JVM不能真正假设目标平台上有一定数量的寄存器可用,因为它应该是平台无关的。因此,它只是将寄存器分配等延迟到JIT编译器。(如果我错了,请纠正我。)
所以Android的家伙想,“嘿,这是低效的,让我们马上去一个基于寄存器的vm."?但是等等,有多个不同的Android设备,Dalvik的目标寄存器数量是多少?Dalvik操作码是针对一定数量的寄存器进行硬编码的吗?
目前市场上所有的Android设备都有相同数量的寄存器吗?或者,在dex加载过程中是否会执行寄存器重新分配?所有这些是如何组合在一起的?

fjnneemd

fjnneemd1#

基于堆栈的VM有几个属性非常符合Java的设计目标:
1.基于堆栈的设计对目标硬件(寄存器、CPU功能)的假设很少,因此很容易在各种硬件上实现VM。
1.由于指令的操作数在很大程度上是隐式的,因此目标代码往往会更小。如果您要通过慢速网络链接下载代码,这一点很重要。
采用基于寄存器的架构可能意味着Dalvik的代码生成器不必像生成高性能代码那样费力。在寄存器非常丰富或寄存器非常贫乏的架构上运行可能会阻碍Dalvik,但这不是通常的目标- ARM是一个非常中间的架构。
我还忘了Dalvik的初始版本根本没有包含JIT。如果你打算直接解释指令,那么基于寄存器的方案可能是解释性能的赢家。

yshpjwxd

yshpjwxd2#

我找不到参考资料,但我认为Sun之所以选择基于堆栈的字节码方法,是因为它使得在寄存器很少的架构(例如IA 32)上运行JVM变得容易。
在Google I/O 2008的Dalvik VM Internals中,Dalvik的创建者Dan Bornsteinpresentation slides的第35张幻灯片上给出了选择基于寄存器的VM的以下参数:
寄存器机器
为什么?为什么?

  • 避免指令分派
  • 避免不必要的内存访问
  • 高效地使用指令流(每个指令的语义密度更高)

在幻灯片36上:
寄存器机器
统计数据

  • 指令减少30%
  • 代码单元减少35%
  • 指令流中的字节数增加35%
  • 但我们可以一次吃两个

根据Bornstein的说法,这是“当你将一组类文件转换为dex文件时,你可以找到的一般期望”。
演示视频的相关部分于25:00开始。
还有一篇题为"Virtual Machine Showdown: Stack Versus Registers" by Shi et al. (2005)的有见地的论文,探讨了基于堆栈和基于寄存器的虚拟机之间的差异。

shstlldc

shstlldc3#

我不知道为什么Sun决定让JVM基于堆栈。Erlangs虚拟机,BEAM是基于寄存器的性能原因。Dalvik似乎也是基于寄存器的性能原因。
Pro Android 2
Dalvik使用寄存器作为数据存储的主要单位,而不是堆栈。Google希望因此可以减少30%的指令。
关于代码大小:
Dalvik VM获取生成的Java类文件,并将它们组合成一个或多个Dalvik可执行文件(.dex)文件。它重用来自多个类文件的重复信息,有效地减少了空间需求(未压缩)从传统的.jar文件减少一半。例如,Android中Web浏览器应用程序的.dex文件约为200k,而等效的未压缩的.jar版本大约是500k。闹钟的.dex文件大约是50k,在其.jar版本中大约是这个大小的两倍。
我记得Computer Architecture: A Quantitative Approach也得出结论,寄存器机器比基于堆栈的机器性能更好。

相关问题