c - GCC 的 __builtin_expect 在 if else 语句中的优势是什么?

我遇到了一个 #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 that exp == c. For example:

      if (__builtin_expect (x, 0))
        foo ();

would indicate that we do not expect to call foo, since we expect x 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/

相关文章:

python - 不可变与可变类型

linux - Bash:无限 sleep (无限阻塞)

python - 如何在 Python 中获取已排序数组的索引

python - 在 Python 中清除终端

python - Virtualenvs 中损坏的引用

linux - 获取图像尺寸(不是文件大小)的快速方法

linux - 释放 TCP/IP 端口?

python - 修改刻度标签文本

python - 如何创建一个全部为 True 或全部为 False 的 numpy 数组?

linux - 如何从远程 SSH session 将数据发送到本地剪贴板