2011-03-20 137 views
4

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

但我不记得这个效果的明确声明。

有没有人知道Java优化(例如由本地代码编译器执行的)是否有效的权威声明(即在JLS或具有类似声誉的文档中)?

+0

通常,单线程场景很简单。多线程是烦人的,因为可以观察到一些优化,特别是对存储器读/写的重新排序。哪种重新排序取决于内存模型,但我不知道java标准指定的内存模型。 – CodesInChaos 2011-03-20 09:59:23

+0

当然,例如:'code_statement; //“有效”优化。 – Margus 2011-03-20 10:25:45

+0

@CodeInChaos - 实际上,对读/写的重新排序是明确指定规则的区域。 – 2011-03-20 13:46:37

回答

3

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

希望这会有所帮助!

+0

是的...但是你能指出什么地方谈论可观察到的行为,并说什么是什么,什么是不可观察的? (我的直觉是,这是采取的方法......但我想要一些明确的确认。) – 2011-03-20 13:45:59

1

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

我不认为有必要特别说明这一事实,因为符合标准的编译器的唯一要求是它的行为与标准描述相同。无论是否符合标准,优化都不会改变其明显的行为。

+0

也许有。例如,积极优化循环(完全删除它们)对于编写天真基准的人来说是“可观察的”。如果您可以指出明确指出此类优化是“有效”的规格,那将是非常好的。 (我认为他们*应该是* ...) – 2011-03-20 13:50:42

+0

@Stephen C:优化可以很好地观察到(如果它们没有*,它们将毫无意义),但是我很确定规范没有对事物的执行时间说很多。只要优化不会改变规范规定的任何内容(执行速度是我希望不会执行的),但它们在遵守标准方面没有任何区别。 – 2011-03-20 15:58:46

+0

@Stephen C:只要观察到的行为(即程序结果)是正确的,一切都很好,规范对速度绝对不感兴趣。此外,优化器可以执行任何不会改变单个线程化程序的执行的任何事情,例如,观察到一个循环变量只读不写,因此用while替换循环(true) - 这会导致在其他线程中设置变量的程序出现问题(显然只有当变量不是易失性的时候) – Voo 2011-03-20 18:25:22