【问题标题】:Unable to understand a statement about compilers' optimization无法理解有关编译器优化的陈述
【发布时间】:2010-11-06 02:40:48
【问题描述】:

我对虚拟机在运行时和编译时的优化感兴趣。我的想法是优化在编译时是最有效和最简单的。

但是,在某些情况下,我的想法似乎是错误的。这在Steve Yeggie's statement quoted by Daniel 中很明显

[O]在运行时由聪明的人执行优化通常更容易 虚拟机 - -。

为什么在运行时由 VM 执行优化比在编译时更容易?

【问题讨论】:

  • 我认为 Steve Yeggie 的意思是“更容易获得更好的结果”而不是“更容易做”,我认为您是这样解释它的。毕竟,我想在程序运行时重新排列程序比在编译时更难。

标签: compiler-construction runtime compile-time vm-implementation


【解决方案1】:

简答:因为在运行时更容易识别和分析热点 - 程序中使用时间最多的部分。

长答案:

如果您开始在解释模式下运行代码,虚拟机可以计算代码不同部分的使用频率和使用时间。这些部分可以得到更好的优化。

采用嵌套的 if-then-else-clauses。更少的布尔检查需要更少的运行时间。如果您优化部件的路径,即更频繁地执行,您可以获得更好的整体运行时间。

另一点是,在运行时您可以做出假设,而这在编译时是不可能的。例如,Java-VM 在服务器模式虚拟方法中内联——只要只加载一个实现这些方法的类。如果在编译时完成,那将是不安全的。如果加载了另一个类,JVM 会再次取消优化代码,但这通常不会发生。

同样在运行时更了解程序运行所在的机器。如果您有一台带有更多寄存器的机器,您可以使用它们。同样,如果在编译时完成也是不安全的。

有一点要说:在运行时优化也有缺点。最重要的是:优化的时间被添加到程序的运行时间中。它也更复杂,因为您必须编译部分程序并执行它们。虚拟机中的错误至关重要。想想一个编译器,它有时会崩溃——你可以再次编译,一切都很好。如果虚拟机有时会崩溃,这意味着您的程序有时会崩溃。不好。

作为结论:您可以在运行时进行所有优化,这在编译时是可能的......等等。你有更多关于程序的信息,它的执行路径和程序正在运行的机器。但是您必须考虑运行优化所需的时间。此外,在运行时执行起来更复杂,并且错误比在编译时更相关。

【讨论】:

  • “你可以在运行时进行所有编译时可能的优化”——我不相信。配置文件引导的优化器可以重新排列对象中数据成员的顺序,例如提高引用的局部性或将最常用的对象移动到偏移量 0。如果内存中已经有实际对象,那几乎是不可能的。
  • 现代垃圾收集器一直在重新排列内存中的对象以减少碎片。为此,必须重写所有引用/指针(或使用一些巧妙的间接)。在这种情况下,重新排列数据成员似乎并不复杂。但我必须承认,我不知道实际执行此操作的 VM 示例。
  • 这实际上非常简单,尤其是因为使用标记清除垃圾收集的 VM 会定期遍历整个对象树。再一次,运行时获胜,因为您可以定期查看真正一起访问的字段,而不是在一个很少调用的方法中。 (注意:我不知道 .Net 或 Java 虚拟机是否真的这样做,我个人怀疑他们这样做)
  • @Mnementh:评论最后一句话:你的意思是运行时的优化比编译时更复杂,而且运行时的错误比编译时更相关。
  • @Masi:错误更相关,因为编译器上的错误不一定会破坏已编译的程序。 VM上的故障是VM上执行的程序的故障。
【解决方案2】:

因为在运行时您有额外的信息:机器的执行情况、进程的内存限制,以及最重要的可能是执行的代码以及执行频率。

这些东西让您可以进行在编译时根本无法进行的运行时优化。

【讨论】:

    【解决方案3】:

    因为在运行时可以获得更多信息。例如,确切的 CPU、操作系统和其他环境细节是已知的。此信息会影响应该如何进行优化。

    【讨论】:

    • 是的 - 例如,编译器通常无法利用 SSE3。
    【解决方案4】:

    VM 有程序的完整代码,而编译器通常只有部分代码,因为不同的翻译单元是分开翻译的。因此,VM 有更多数据可供分析。

    【讨论】:

      【解决方案5】:

      VM 可以收集统计数据以进行优化,就像数据库对您的使用情况所做的那样。

      【讨论】:

        【解决方案6】:

        持续保持统计数据和检查不变量也会增加编译或解释片段的执行时间。如果您不能快速和足够好地优化,请不要打扰。我认为在运行时而不是编译时获得更好的结果并不容易。考虑到一个好的实现的复杂性,我认为这更加困难。

        就像一个普遍的误解,即足够好的优化编译器比人类生成更好的汇编,足够聪明的 VM 可能需要太聪明才能执行得更快。

        【讨论】:

          【解决方案7】:

          需要认识到的是,允许运行时优化的不是 VM 的概念,而是许多 VM 不会丢弃原始程序元数据并具有内置反射功能的事实。一个更合适的术语是“运行时库”可以比单独的静态优化做更好的优化;这适用于 C 等非 VM 语言。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-29
            • 1970-01-01
            相关资源
            最近更新 更多