gcc可能不太可能使用宏

时间:2012-06-06 21:29:24

标签: performance gcc memory likely-unlikely

我正在用大致以下逻辑编写一段关键代码

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
}

我想在表达式周围使用possible()宏,所以当它到达重要分支时,我得到最小延迟。我的问题是,使用方法与宏名称的建议完全相反,因为我选择“不太可能”的分支进行预取。在绩效方面这样做有明显的缺点吗?

2 个答案:

答案 0 :(得分:9)

是。你是通过标记不太可能但必须快速的分支来欺骗编译器,好像它是可能的分支一样,希望编译器能让它更快。

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

还有一个不太可能但仍有可能的缺点,你现在或将来使用的某些版本的编译器会做出与你对可能的宏所期望的不同的事情,那些不同的东西将不会是你想要欺骗编译器做什么,你最终得到的代码,每次循环,花费10万美元投机地通过反应堆关闭90%,然后撤消它。

答案 1 :(得分:4)

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

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

我个人认为这是一种糟糕的形式(因为你可能会将不太可能的路径标记为性能增益)。但是,您仍然可以标记此优化,因为__builtin_expect(x)不会通过声称路径“喜欢”来对您的需求做出任何假设 - 这只是标准用途。为了做您想做的事情,我建议:

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

这将做同样的事情,但不是让代码指责不太可能的路径,你现在正在让代码描述你真正想要的 - 优化关键路径。

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