我正在阅读一个文档,该文档讨论了Java的即时编译器(JIT)优化技术。其中之一是“循环反转”。文件说:
您将常规
while
循环替换为do-while
循环。而do-while
循环的中设置if
条款。这种替换导致更少的两次跳跃。
循环反转如何工作以及如何优化我们的代码路径?
注意: 如果有人可以用Java代码示例进行解释,以及JIT如何将其优化为本地代码以及为什么在现代处理器中是最佳的,那将是很棒的。
我正在阅读一个文档,该文档讨论了Java的即时编译器(JIT)优化技术。其中之一是“循环反转”。文件说:
您将常规
while
循环替换为do-while
循环。而do-while
循环的中设置if
条款。这种替换导致更少的两次跳跃。
循环反转如何工作以及如何优化我们的代码路径?
注意: 如果有人可以用Java代码示例进行解释,以及JIT如何将其优化为本地代码以及为什么在现代处理器中是最佳的,那将是很棒的。
Answers:
while (condition) {
...
}
工作流程:
if (condition) do {
...
} while (condition);
工作流程:
比较这两者,您可以轻松地看到,如果循环中只有一个步骤,则后者可能根本不执行任何跳转,并且通常,跳转的次数将比迭代的次数少一个。前者将不得不跳回检查条件,仅当条件为假时才跳出循环。
现代流水线CPU架构上的跳转可能会非常昂贵:随着CPU在跳转之前完成检查的执行,该跳转之外的指令已经在流水线的中间。如果分支预测失败,则必须放弃所有此处理。在重新启动管道时,进一步执行被延迟。
解释上述分支预测:对于每种条件跳转,CPU都有两条指令,每条指令都包含对结果的押注。例如,您将在循环的末尾放置一条指令,说“ 如果不为零则跳转,下注为非零 ”,因为跳转必须在除最后一次迭代之外的所有迭代中进行。这样,CPU开始使用跳转目标后的指令而不是跳转指令后的指令来泵送其管道。
请不要不以此为如何在源代码级优化的例子。这已经完全被误导了,因为从您的问题中已经很清楚地知道,从第一种形式到第二种形式的转换是JIT编译器作为例程完全由自己完成的事情。
do-while
源代码生成的字节码是无关紧要的,因为我们实际上并没有编写它。我们编写while
循环,让编译器和JIT共同(如果需要)(通过循环反转)为我们改进循环。
这样可以优化始终至少执行一次的循环。
然后,常规while
循环将始终至少跳回到起点一次,并在末尾跳一次到终点。一个运行一次的简单循环的示例:
int i = 0;
while (i++ < 1) {
//do something
}
一个do-while
在另一方面循环将跳过第一个和最后一个跳跃。这是与上述循环等效的循环,将无跳跃地运行:
int i = 0;
if (i++ < 1) {
do {
//do something
} while (i++ < 1);
}
boolean b = true; while(b){ b = maybeTrue();}
想要的东西boolean b;do{ b = maybeTrue();}while(b);
就足够了。
让我们来看一下它们:
while
版本:void foo(int n) {
while (n < 10) {
use(n);
++n;
}
done();
}
n
并跳至done();
条件是否为真。n
。done()
。do-while
版本:(请记住,我们实际上并没有在源代码中执行此操作(这会带来维护问题),编译器/ JIT会为我们执行此操作。)
void foo(int n) {
if (n < 10) {
do {
use(n);
++n;
}
while (n < 10);
}
done();
}
n
并跳至done();
条件是否为真。n
。done()
。因此,例如,如果n
从头开始9
,我们就不会在do-while
版本中完全跳过,而在while
版本中,我们必须跳回到开头,进行测试,然后在发现不正确时跳回到结尾。 。
循环反转是一种性能优化技术,可提高性能,因为处理器可以用更少的指令来完成相同的结果。这应该主要改善边界条件下的性能。
该链接提供了循环反转的另一个示例。在少数将递减和比较实现为单个指令集的体系结构中,使用递减和比较操作将for循环转换为while是有意义的。
维基百科有一个很好的例子,我在这里再次解释。
int i, a[100];
i = 0;
while (i < 100) {
a[i] = 0;
i++;
}
将由编译器转换为
int i, a[100];
i = 0;
if (i < 100) {
do {
a[i] = 0;
i++;
} while (i < 100);
}
这如何转化为性能? 当i的值为99时,处理器无需执行GOTO(在第一种情况下是必需的)。这样可以提高性能。