GCC 的__builtin_expect程序集转储似乎总是下降分支
GCC's __builtin_expect assembly dump seems to always go down branch
好的,所以我一直在玩__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;
}
}
当使用- 01或更大的值编译时会产生:
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标志设置为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,即使它指定它需要很长时间?
From the docs:
返回值是exp的值,应该是一个整型表达式。
的逻辑语义是:
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)) { ... }
相关文章:
- 分段故障(堆芯转储)矢量
- Cppcheck生成xml转储文件
- 如何找出GDB的SIGTRAP核心转储的根本原因
- C++映射分割错误(核心转储)
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 浮点异常(核心转储)#694457
- 分段错误(核心转储)但无法弄清楚
- 链接到libkcapi时没有核心转储
- 检测到堆栈粉碎:已终止 中止(核心已转储)
- 正在处理故障(堆芯转储)
- 分段错误(核心转储) - 使用 SavedModel 的 Tensorflow C++ API 进行推断
- 我不知道为什么这段代码会让核心被转储?
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 在基数排序中,我得到 munmap_chunk():无效指针和中止(核心转储).为什么?
- C++指针无法在函数外部传递值和分段错误(核心转储)错误
- cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 class4.exe.sta
- C++快速将 int 数组内容转储到文本文件中
- 合并排序:分段错误核心转储
- GCC 的__builtin_expect程序集转储似乎总是下降分支