Java if语句结构和指令流水线

时间:2016-07-20 22:15:22

标签: java performance cpu-architecture

问题:这更多是为了好奇而不是其他任何事情。如果我有一个Java if/else语句,并且我知道' if / else'的一个分支。语句将比其他分支更频繁地使用,我订购这两个分支的方式是否可以为JIT编译器提供一个提示,从而获得更好的性能?

背景 在我对计算机体系结构的简单看法中,“如果/其他'除其他事项外,语句被转换为条件跳转指令,后跟在执行跳转时应执行的指令。内存中的其他位置将是跳转所针对的代码。据我了解,CPU会尽可能地按顺序加载指令(我确定我在这里忽略了分支预测器),并且非跳转路径更有可能被加载到指令中缓存和CPU的指令管道。

问题重述: if/else语句分支的合理排序是否会增加经常执行的代码紧跟条件跳转指令的可能性,条件跳转指令将呈现代码对缓存和管道都更友好了吗?

现实:听到JIT编译器是如此复杂的软件,在完成所有指令重新排序,寄存器分配和其他簿记后,我不会感到惊讶,它不能做出这样的保证。

我的大多数' if / else'语句将不会被执行,所以我不会在任何地方这样做。此外,很多时候我会猜错哪个分支会更频繁地执行,最终会损害性能。

我想认为像分支排序故意这样简单的事情不会被认为是过早的优化,但如果是,如果分析器向我显示代码,我只会弄乱排序很慢。

谢谢!

1 个答案:

答案 0 :(得分:3)

没有

你不能。你不需要。

它对编译器有意义,因为它可以翻译

if (improbable) {
    doSomething();
} else {
    doSomethingElse();
}
doMoreThings();
return;

进入(伪代码)

if (improbable) goto away
doSomething()
back: doMoreThings()
return
away: doSomethingElse()
goto back

这样可以简化更可能的路径。 AOT编译器可以依赖提供的信息。

您不需要。但是Java JIT编译器在收集统计信息后会一直这样做。在这里,javac是无关紧要的,因为字节码被解释器执行了几次,这很慢,但对于很少执行的部分和足以收集统计信息的部分来说已经足够了。通常,这些统计数据优于程序员可能提供的数据,但重要的是:它们是为每个时间相关的代码收集的。它实际上更复杂,因为那里有C1和C2编译器......

你不能。在字节码中没有标准化的表达方式。此外,优化器会在内部表示中转换代码,这些细节会丢失。

过早优化忘了它。编译器可以很好地完成更复杂的事情。一些低级优化仍然有意义,但仅限于非常极端的情况。如果需要,可以使用干净的代码和可能进行一些高级优化。