【问题标题】:gcc likely unlikely macro usagegcc 可能不太可能使用宏
【发布时间】:2012-06-10 23:08:24
【问题描述】:

我正在编写一段关键的代码,其逻辑大致如下

if(expression is true){
   //do something with extremely low latency before the nuke blows up. This branch is entered rarely, but it is the most important case
}else{
   //do unimportant thing that doesnt really matter
}

我正在考虑在表达式周围使用likely() 宏,因此当它到达重要分支时,我会得到最小的延迟。

我的问题是,它的用法与建议的宏名称完全相反,因为我选择 unlikely 分支进行预取,也就是说,重要的分支不太可能发生,但它是发生时最关键的事情。

在性能方面这样做有明显的缺点吗?

【问题讨论】:

  • 您没有选择任何分支来进行 prefetch,您只是标记代码以便编译器优化 可能 的情况,这可能包括为该分支生成具有更好局部性的代码,但没有明确的 prefetch.
  • #define likely(x) __builtin_expect((x),1) 似乎是你想要的,你的意思是它的用法与它的名字相反?
  • @nos 重要的分支不太可能发生,但发生时才是最关键的。
  • 我希望我不会住在顺风。相信编译器优化器能够提出足够好的优化以赶上最后期限是非常值得信任的。
  • 您确定它可以产生可衡量的差异吗?

标签: performance gcc memory likely-unlikely


【解决方案1】:

是的。您通过将不太可能但必须快速的分支标记为可能的分支来欺骗编译器,希望编译器能够使其更快。

这样做有一个明显的缺点——如果你没有写一个很好的评论来解释你在做什么以及为什么,在六个月内,一些维护者(可能是你自己)几乎肯定会说,“嘿,看起来他把可能的分支放在了错误的分支上”并“修复”它。

还有一个不太可能但仍然可能的缺点,即您现在或将来使用的某些编译器版本将执行与您对可能的宏的预期不同的事情,并且这些不同的事情不会你想欺骗编译器做的事情,你最终会得到这样的代码,每次通过循环,在撤消它之前,你会花费 10 万美元推测性地通过反应器关闭的 90%。

【讨论】:

  • 一个更好的宏名称选择可能是“关键的”,特别是如果它实际上涉及核反应。或者也许是“must_be_performed_fast”。由于您使用的是宏,因此宏名称可以表明您需要它的原因;实现隐藏在宏名称后面。
  • @JonathanLeffler:非常好的主意。这样,您可以将恐慌注释放在宏的实现中,而不是在每次使用时。而且,更重要的是,您可以一次更改它的所有用途。
【解决方案2】:

它与传统的使用__builtin_expect(x, 1)完全相反,它是在宏的意义上使用的:

#define likely(x) __builtin_expect(x, 1)

我个人认为这是不好的形式(因为您隐晦地将不太可能的路径标记为可能会提高性能)。但是,您仍然可以标记此优化,因为 __builtin_expect(x) 不会通过声明“likey”路径来假设您的需求 - 这只是标准用途。我建议:

#define optimize_path(x) __builtin_expect(x, 1)

这将做同样的事情,但不是让代码指责不太可能的路径,而是让代码描述你真正尝试的内容——优化关键路径。

但是,我应该说,如果您计划对 nuke 进行计时 - 您不仅应该手动检查(和计时)已编译的程序集以确保计时正确,而且您还应该使用 RTOS。分支错误预测将产生非常微不足道的影响,以至于在这里几乎没有必要,因为您可以通过简单地拥有更快的处理器或正确地为错误预测的延迟计时来补偿“百万分之一”事件。影响现代计算机时序的是操作系统抢占和调度。如果您需要在非常离散的时间尺度上发生某些事情,您应该将它们安排为实时,而不是大多数通用操作系统所具有的伪实时。分支错误预测通常比在 RT 情况下不使用 RTOS 可能发生的延迟小数百倍。通常,如果您认为分支预测错误可能是一个问题,您可以从时间敏感问题中删除分支,因为分支预测器通常具有复杂且不受您控制的状态。宏之类的“可能”和“不太可能”适用于可以从各个区域命中的代码块,具有各种分支预测状态,最重要的是非常频繁地使用。命中这些分支的高频率导致使用它的应用程序(如 Linux 内核)的性能显着提高。如果您只点击一次分支,可能在某些情况下会获得 1 纳秒的性能提升,但如果应用程序对时间至关重要,那么您可以做其他事情来帮助自己变得更大性能提升。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2013-12-01
    • 2014-05-12
    • 2021-12-19
    • 2010-11-29
    • 2016-11-16
    • 1970-01-01
    相关资源
    最近更新 更多