我遇到了一个 #define
,他们在其中使用了 __builtin_expect
。
The documentation说:
Built-in Function:
long __builtin_expect (long exp, long c)
You may use
__builtin_expect
to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (-fprofile-arcs
), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.The return value is the value of
exp
, which should be an integral expression. The semantics of the built-in are that it is expected thatexp == c
. For example:if (__builtin_expect (x, 0)) foo ();
would indicate that we do not expect to call
foo
, since we expectx
to be zero.
那么为什么不直接使用:
if (x)
foo ();
用 __builtin_expect
代替复杂的语法?
最佳答案
想象一下将生成的汇编代码:
if (__builtin_expect(x, 0)) {
foo();
...
} else {
bar();
...
}
我想应该是这样的:
cmp $x, 0
jne _foo
_bar:
call bar
...
jmp after_if
_foo:
call foo
...
after_if:
您可以看到指令的排列顺序是 bar
情况在 foo
情况之前(与 C 代码相反)。这可以更好地利用 CPU 流水线,因为跳转会破坏已经获取的指令。
在执行跳转之前,它下面的指令(bar
情况)被推送到管道。由于不太可能出现 foo
的情况,因此也不太可能发生跳跃,因此不太可能破坏管道。
https://stackoverflow.com/questions/7346929/