【问题标题】:Java specifications - what are the rules for a "valid" optimizationJava 规范——“有效”优化的规则是什么
【发布时间】:2011-03-20 09:44:53
【问题描述】:

我的理解是,如果优化没有与 JLS 相矛盾的可观察效果,​​则优化是有效的。例如,JIT 编译器可以优化掉内部循环中“什么都不做”的代码。

但我不记得有明确的声明。

是否有人知道 Java 优化(例如由本机代码编译器执行)何时有效的明确声明(即在 JLS 或类似文件中)?

【问题讨论】:

  • 通常单线程场景很简单。多线程很烦人,因为可以观察到一些优化,特别是内存读/写的重新排序。允许哪些重新排序取决于内存模型,但我不知道 java 标准指定了哪种内存模型。
  • 可以,例如:code_statement; // “valid” optimization.
  • @CodeInChaos - 实际上,读/写的重新排序是明确规定规则的领域。
  • @CodeInChaos:优化器可以做每一个不会改变程序单线程执行的优化,所以我们可以做很多。
  • @Voo 很有趣。所以Java的内存比.net弱很多。

标签: java optimization specifications


【解决方案1】:

JLS 和 JVM 规范都指定了任何 Java 语句的行为(或 JVM 规范字节码如何工作等),但他们没有说明 如何 该行为是发生。在这两个文档中隐含的是,任何正确实现指定的抽象行为的实现都被认为是兼容的 Java 实现。拥有抽象标准背后的主要思想是指定必须在所有实现之间共享哪些可观察行为,而无需深入了解导致这些行为发生的细节。出于这个原因,只要不偏离指定的语义,实现及其优化器就可以做任何他们认为必要和适当的事情以使代码运行。

希望这会有所帮助!

【讨论】:

  • 是的......但是你能指出规范中讨论可观察行为的地方,并说明什么是可观察的,什么是不可观察的? (我的直觉是,这是采取的方法......但我想要一些明确的确认。)
【解决方案2】:

编译器优化是有效的,只要它不会使代码的行为与标准不同。这适用于所有语言。

我认为没有必要具体说明这一事实,因为对符合标准的编译器的唯一要求是它的行为与标准描述的一样。不改变其明显行为的优化显然不会改变它是否符合标准。

【讨论】:

  • 也许有。例如,循环的积极优化(甚至完全删除它们)对于编写幼稚基准的人来说是“可观察到的”。如果您能指出规范中明确指出此类优化是“有效的”的地方,那就太好了。 (而且我认为他们应该是 ...)
  • @Stephen C:优化很可能是可观察到的(如果他们什么都不做,那么它们将毫无意义),但我很确定规范并没有说太多关于事情的执行时间。只要优化不改变规范指定的任何内容(我希望它不会改变执行速度),它们对标准合规性没有影响。
  • @Stephen C:规范对速度绝对不感兴趣,只要观察到的行为(即程序的结果)是正确的,一切都很好。优化器也可以做任何不会改变单线程程序执行的事情,例如观察到循环变量只是读取而不是写入,因此用 while(true) 替换循环 - 这将导致在另一个线程中设置变量的程序出现问题(显然只有当变量不是易失性时)
【解决方案3】:

例如这里提到的String pool 是一种优化形式。对于 Integer 和 Long 的小值,存在类似的概念。

也许你可以在这里找到更多interesting answers hereInteger pool 的解释。

【讨论】:

    猜你喜欢
    • 2019-07-07
    • 2011-01-05
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2018-01-26
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多