【问题标题】:Why is the JVM stack-based and the Dalvik VM register-based?为什么 JVM 是基于栈的,而 Dalvik VM 是基于寄存器的?
【发布时间】:2011-02-12 18:01:40
【问题描述】:

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

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

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

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

【问题讨论】:

  • Google 是否决定让 DalvikVM 基于寄存器?我认为 DalvikVM 是在 Google 收购 Android Inc. 之前实施的。
  • 你当然是对的。 (虽然与问题不太相关;)

标签: jvm dalvik cpu-registers computer-architecture vm-implementation


【解决方案1】:

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

  1. 基于堆栈的设计很少 关于目标的假设 硬件(寄存器、CPU 功能)、 所以很容易在一个虚拟机上实现 各种硬件。

  2. 由于指令的操作数 在很大程度上是隐含的,对象 代码往往会更小。这 如果你想成为 缓慢下载代码 网络链接。

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


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

【讨论】:

  • 好的,这很有趣。那么 DalvikVM 是否假设目标设备上的寄存器数量最少?
  • 另外,我读到有些人正在他们的笔记本电脑上安装 Android,因为它是一个“轻量级”操作系统......如果笔记本电脑不是 ARM,这似乎是个坏主意,也许有一个包含许多寄存器的架构?
  • 好的,我刚刚了解到 dex 字节码是根据无限寄存器机器定义的,说到效率,它似乎主要是关于内存占用。
  • 我不记得 Dalvik 是基于无限寄存器,还是具有固定的寄存器文件大小。如果它是无限的,那么它往往会在对您正在运行的任何代码具有“足够”寄存器的架构上表现最佳。
  • 更详细的解释可以在这里找到:markfaction.wordpress.com/2012/07/15/…
【解决方案2】:

我不知道 Sun 为何决定基于 JVM 堆栈。 Erlangs 虚拟机,BEAM 出于性能原因是基于寄存器的。由于性能原因,Dalvik 似乎也是基于寄存器的。

来自Pro Android 2

Dalvik 使用寄存器作为主要的数据存储单元,而不是堆栈。 Google 希望因此能够减少 30% 的指令。

关于代码大小:

Dalvik VM 获取生成的 Java 类文件并将它们组合成一个或多个 Dalvik 可执行文件 (.dex) 文件。它重用了来自多个类文件的重复信息,有效地将空间需求(未压缩)比传统的 .jar 文件减少了一半。例如,Android 中的网络浏览器应用程序的 .dex 文件约为 200k,而等效的未压缩 .jar 版本约为 500k。闹钟的 .dex 文件大小约为 50k,大约是 .jar 版本的两倍。

我记得Computer Architecture: A Quantitative Approach 还得出结论,寄存器机器比基于堆栈的机器性能更好。

【讨论】:

  • 如果我不得不猜测,我会说 Sun 决定基于 JVM 堆栈,因为它比注册机更容易实现。 (但要付出不小的性能成本,如此处所述。)
  • 我找不到参考资料,但我认为 Sun 决定采用基于堆栈的字节码方法,因为它可以轻松地在低寄存器架构上运行 JVM。
  • 对于硬件 ISA,是的,注册机器已经赢了。基本上每个 CPU / 微控制器都是一台寄存器机器,因为相比之下其他一切都很糟糕。有些有非常很少个寄存器,比如只有一个累加器,可能还有一个或两个指针或索引寄存器,但这更像是计算理论意义上的寄存器机器。但是我们讨论的是解释的虚拟机,所以如果有的话,“注册文件”实际上会在内存中。除非你 JIT 编译为本机代码。 reg 比 stack 快的原因有很大不同。
【解决方案3】:

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

在来自 Google I/O 2008 的 Dalvik VM Internals 中,Dalvik 创建者 Dan Bornsteinpresentation slides 的幻灯片 35 上提供了以下论点,用于选择基于寄存器的 VM:

注册机器

为什么?

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

在幻灯片 36 上:

注册机器

统计数据

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

根据 Bornstein 的说法,这是“将一组类文件转换为 dex 文件时可以找到的一般预期”。

presentation video starts at 25:00的相关部分。

还有一篇名为"Virtual Machine Showdown: Stack Versus Registers" by Shi et al. (2005) 的有见地的论文探讨了基于堆栈和基于寄存器的虚拟机之间的区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 2011-07-03
    • 2012-01-31
    • 2017-01-27
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    相关资源
    最近更新 更多