【问题标题】:guidelines on using __builtin_expect使用 __builtin_expect 的指南
【发布时间】:2026-01-02 00:50:01
【问题描述】:

我应该用 gcc 的 __builtin_expected 宏在 if 中包含多个嵌套测试吗?我有这个代码:

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)))))

我希望这只是矫枉过正,因为它几乎无法阅读。

【问题讨论】:

  • 您打算在哪里运行此代码?在现代 x86 CPU 上的实践中,无论如何,分支预测器都比静态提示好得多,即,如果您经常运行代码并且有一个简单的模式,它们会很容易地找到它。如果您经常运行代码,为什么您认为几个周期会很重要?现在,如果您的目标平台之一是 ARM,这可能不是一个坏主意。

标签: optimization gcc built-in


【解决方案1】:

我认为这里没有错误的答案。编译器将使用您的提示来决定每次比较的“其他”情况;这不仅是 C 代码 else,而且在逻辑的 andsors 中也是如此,并且信息越多越好。

为了代码的可读性,我建议将其保留为大的东西:每个 if 语句一次,但这并不是基于任何确凿的证据。

您是否考虑过使用-fprofile-generate,使用典型数据运行代码,然后使用-fprofile-use 重新构建?这样编译器就可以为所有这些情况构建自己的图片。这更便携(没有特定于编译器的注释)、更具可读性和更面向未来。

【讨论】: