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

问题描述 投票:0回答:4

我很好奇,为什么Sun决定让JVM基于堆栈,而Google决定让DalvikVM基于寄存器?

我认为 JVM 不能真正假设目标平台上有一定数量的寄存器可用,因为它应该是独立于平台的。因此,它只是将寄存器分配等推迟到 JIT 编译器。 (如果我错了请纠正我。)

所以 Android 人员想,“嘿,这效率很低,让我们立即使用基于寄存器的虚拟机......”?但是等等,有多个不同的 Android 设备,Dalvik 的目标寄存器数量是多少? Dalvik 操作码是否针对一定数量的寄存器进行了硬编码?

当前市场上所有 Android 设备的寄存器数量都大致相同吗?或者,在 dex 加载期间是否执行了寄存器重新分配?所有这些如何结合在一起?

jvm dalvik cpu-registers cpu-architecture vm-implementation
4个回答
73
投票

基于堆栈的 VM 有一些属性非常适合 Java 的设计目标:

  1. 基于堆栈的设计使得很少 关于目标的假设 硬件(寄存器、CPU 功能)、 所以很容易在 各种硬件。

  2. 自指令操作数 很大程度上是隐式的,对象 代码往往会更小。这 如果你想成为的话,这一点很重要 下载代码速度很慢 网络链接。

采用基于寄存器的方案可能意味着 Dalvik 的代码生成器不必努力工作来生成高性能代码。在寄存器极其丰富或寄存器极其匮乏的架构上运行可能会妨碍 Dalvik,但这不是通常的目标 - ARM 是一种非常中间的架构。


我还忘记了 Dalvik 的初始版本根本不包含 JIT。如果您要直接解释指令,那么基于寄存器的方案可能是解释性能的赢家。


37
投票

我找不到参考资料,但我认为 Sun 决定采用基于堆栈的字节码方法,因为它可以轻松地在寄存器很少的架构(例如 IA32)上运行 JVM。

在 Google I/O 2008 的 Dalvik VM 内部结构中,Dalvik 创建者 Dan Bornstein演示幻灯片的第 35 张幻灯片中给出了以下关于选择基于寄存器的 VM 的论点:

注册机

为什么?

  • 避免指令发送
  • 避免不必要的内存访问
  • 高效使用指令流(每条指令具有更高的语义密度)

在幻灯片 36 上:

注册机

统计数据

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

根据 Bornstein 的说法,这是“当你将一组类文件转换为 dex 文件时你会发现的一般期望”。

演示视频的相关部分于25:00开始

还有一篇由 Shi 等人撰写的富有洞察力的论文,标题为

“虚拟机对决:堆栈与寄存器”。 (2005),探讨了基于堆栈和基于寄存器的虚拟机之间的差异。


14
投票
我不知道为什么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 版本大小的两倍。

我记得

计算机体系结构:定量方法还得出结论,寄存器机比基于堆栈的机器性能更好。


0
投票

基于堆栈与基于寄存器的虚拟机架构,以及 Dalvik VM

“寄存器在 Dalvik 中作为 4 位字段实现。”根据这个博客

© www.soinside.com 2019 - 2024. All rights reserved.