gpt4 book ai didi

c++ - GCC 的 __builtin_expect 程序集转储似乎总是下降分支

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

好吧,我一直在玩弄 __builtin_expect,我刚刚创建了一个简单的测试程序,我通过 godbolt.org 获取程序集输出 (https://godbolt.org/g/FZo5fP)

int main(){
volatile int num = 4;
//if(num == 4){
if(__builtin_expect(num,4)){
return num*800;
}else{
return num*500;
}
}

当使用 -O1 或更高版本编译时产生:

main:
mov DWORD PTR [rsp-4], 4
mov eax, DWORD PTR [rsp-4]
test eax, eax
mov eax, DWORD PTR [rsp-4]
je .L2
imul eax, eax, 800
ret
.L2:
imul eax, eax, 500
ret

似乎说 test eax,eax 的部分总是将零标志设置为 0,除非 num 等于 0。所以看起来好像 num 未设置为 0,它将始终乘以 800 而不是仅当 num=4 时。我对 __builtin_expect 的理解是,虽然它会优化以假设它将转到该分支,但它仍应进行比较以确保它应该使用该分支。

如果我将 __builtin_expect 切换为 == 它会产生

main:
mov DWORD PTR [rsp-4], 2
mov eax, DWORD PTR [rsp-4]
cmp eax, 4
mov eax, DWORD PTR [rsp-4]
je .L5
imul eax, eax, 500
ret
.L5:
imul eax, eax, 800
ret

这对我来说更有意义,因为它实际上与 4 相比。我对 __builtin_expect 的理解是错误的吗? __builtin_expect 实际上只适用于 0 或 1,即使它指定它需要很长时间吗?

最佳答案

来自 the docs :

The return value is the value of exp, which should be an integral expression.

所以逻辑语义:

if(__builtin_expect(num,4)) { ... }

是:

if (num) { ... }

这和你说的不一样。如果你想写出你期望 num == 4 的可能性很大,你需要:

if (__builtin_expect(num == 4, 1)) { ... }

通常,您只需将它们包装在宏中:

#define likely(expr)   __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)

然后用法变得更自然:

if (likely(num == 4)) { ... }

关于c++ - GCC 的 __builtin_expect 程序集转储似乎总是下降分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40390583/

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