gpt4 book ai didi

c - 可能(x)和 __builtin_expect((x),1)

转载 作者:太空狗 更新时间:2023-10-29 17:20:35 29 4
gpt4 key购买 nike

我知道内核大量使用 likelyunlikely 宏。宏的文档位于 Built-in Function: long __builtin_expect (long exp, long c)。 .但他们并没有真正讨论细节。

编译器究竟如何处理 likely(x)__builtin_expect((x),1)

它是由代码生成器还是优化器处理的?

它是否取决于优化级别?

生成的代码示例是什么?

最佳答案

我刚刚在 gcc 上测试了一个简单的例子。

对于 x86,这似乎由优化器处理并取决于优化级别。虽然我猜这里的正确答案是“这取决于编译器”。

生成的代码依赖于 CPU。一些 cpus(sparc64 立即进入我的脑海,但我敢肯定还有其他的)在条件分支指令上有标志,告诉 CPU 如何预测它,因此编译器根据构建的生成“预测真/预测假”指令在编译器的规则和代码的提示中(如 __builtin_expect)。

英特尔在此处记录了他们的行为:https://software.intel.com/en-us/articles/branch-and-loop-reorganization-to-prevent-mispredicts .简而言之,英特尔 CPU 的行为是,如果 CPU 没有关于分支的先前信息,它将预测前向分支不太可能被采用,而向后分支很可能被采用(考虑循环与错误处理)。

这是一些示例代码:

int bar(int);
int
foo(int x)
{
if (__builtin_expect(x>10, PREDICTION))
return bar(10);
return 42;
}

编译(我使用 omit-frame-pointer 使输出更具可读性,但我仍然在下面清理它):

$ cc -S -fomit-frame-pointer -O0 -DPREDICTION=0 -o 00.s foo.c
$ cc -S -fomit-frame-pointer -O0 -DPREDICTION=1 -o 01.s foo.c
$ cc -S -fomit-frame-pointer -O2 -DPREDICTION=0 -o 20.s foo.c
$ cc -S -fomit-frame-pointer -O2 -DPREDICTION=1 -o 21.s foo.c

00.s 和 01.s 之间没有区别,这表明这取决于优化(至少对于 gcc 而言)。

这是为 20.s 生成的(清理过的)代码:

foo:
cmpl $10, %edi
jg .L2
movl $42, %eax
ret
.L2:
movl $10, %edi
jmp bar

这里是 21.s:

foo:
cmpl $10, %edi
jle .L6
movl $10, %edi
jmp bar
.L6:
movl $42, %eax
ret

正如预期的那样,编译器重新安排了代码,以便我们不希望采用的分支在前向分支中完成。

关于c - 可能(x)和 __builtin_expect((x),1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24301397/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com