使用__builtin_expect的指南

4

我应该在具有多个和嵌套测试的if语句中,用gcc的__builtin_expected宏包装什么?我有以下代码:

if((x<RADIUS && (forward?v<0:v>0)) || (x+RADIUS>dimensions[d] && (forward?v>0:v<0)))

我已经(非常)将所有可能的东西都包裹起来:

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)
if(unlikely(unlikely(unlikely(x<RADIUS) && likely(likely(forward)?likely(v<0):likely(v>0))) || unlikely(unlikely(x+RADIUS>dimensions[d]) && likely(likely(forward)?likely(v>0):likely(v<0)))))

我希望这只是一种过度设计,因为它现在几乎无法阅读。


4
你计划在哪里运行这段代码?实际上,在现代的x86 CPU上,分支预测器比静态提示要好得多。也就是说,如果你经常运行代码,并且存在简单的模式,它们会很容易地捕捉到它。如果你不经常运行代码,那么为什么你认为几个周期会很重要呢?现在,如果你的目标平台之一是ARM,这可能不是一个坏主意。 - Voo
1个回答

4
我认为这里没有错误答案。编译器将使用您的提示来决定每个比较的“else”情况; 这不仅是C代码中的else,而且还包括逻辑中的and和or,信息越多越好。
为了可读性,我建议仅保留大体内容:每个if语句只有一次,但这并不是基于任何硬证据。
您考虑过使用-fprofile-generate,用典型数据运行代码,然后重新构建-fprofile-use吗?这样编译器就可以为所有这些情况构建自己的图片。这更具可移植性(无需特定于编译器的注释),更易读,也更具未来性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接