为什么底部测试循环更可取?

Joh*_*ugo 5 compiler-construction x86 assembly gcc llvm

我听说有人说编译器经常将循环条件移到循环的底部.也就是说,像这样的循环:

while (condition) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

改为:

if (condition) {
     do {
         ...
     } while (condition);
}
Run Code Online (Sandbox Code Playgroud)

关于机器独立优化,为什么后者更可取?

Mik*_*wan 7

没有编译器优化,第一个循环转到汇编代码,如下所示:

  @@:
cmp ... ; or test ...
jz @f

...
jmp @b
Run Code Online (Sandbox Code Playgroud)

而第二个循环是这样的:

jmp bottom

  @@:
...

  bottom:
cmp ... ; or test ...
jz @b
Run Code Online (Sandbox Code Playgroud)

通常预测会进行条件跳转,因此第一种方法可能会导致更多的管道/指令缓存刷新.

但是,最重要的是,对于第一个循环,每个循环迭代(2N)有两个分支可用,而在第二个循环中,每个循环迭代只有一个分支具有第一个无条件跳转(N+1)的固定开销.

有关循环优化的更多信息,请参见本程序集优化指南的第88页.

  • 但是,提及分支预测器的+1,您忘记了第二个示例中的无条件跳转.(第二个例子是`do`循环,我们想要一个`while`循环.)你说第二个循环占用的空间更少是错误的. (2认同)