BOOST_LIKELY和__builtin_expect仍然相关吗?

Ael*_*ian 9 assembly gcc boost intel

我理解这里解释的内容以及这些内容包括CPU对静态分支预测的提示.

我想知道英特尔CPU上的这些是如何相关的,因为英特尔CPU已经放弃了对这里提到的静态预测提示的支持.此外,如果我理解它现在如何工作,路径中的分支指令的数量将是编译器可以控制的唯一事物,并且在运行时决定预测,获取和解码哪个分支路径.

鉴于此,是否存在代码中的分支提示对于针对最近的英特尔处理器的软件仍然有用的情况,可能使用条件返回或者在嵌套的if/else语句的情况下避免关键路径中的分支指令数量?

此外,如果这些仍然相关,那么gcc和其他流行编译器的任何细节都会受到赞赏.

PS我不是为了过早优化或者用这些宏来编写代码,但是我对这个主题很感兴趣,因为我正在使用一些时间关键代码,并且仍然希望尽可能减少代码混乱.

谢谢

Gri*_*tov 3

正如在您的问题的评论部分中您正确地发现:

  1. Intel x86 CPU 上的操作码映射中不再有静态分支预测提示;
  2. “冷”条件跳转的动态分支预测往往会预测失败路径;
  3. 编译器可以用来__builtin_expect重新排序 if-then-else 构造的路径将作为生成的程序集中的失败情况放置。

现在,考虑为多个目标架构编译的代码库,而不仅仅是 Intel x86。其中很多确实具有静态分支提示、不同复杂度的动态分支预测器,或两者兼而有之。

例如,英特尔安腾架构确实为所有类型的指令提供了广泛的预测提示系统:控制流、加载/存储等。安腾的设计目的是让编译器对代码进行广泛优化,并在其中包含所有这些静态分配的指令槽。捆绑包和提示。

因此,__builtin_expect对于以下(罕见)情况仍然相关:1)编译器很难自动推断出正确的分支预测信息,2)至少一种目标架构上的底层硬件也已知无法可靠地预测它们动态地。鉴于某些低功耗处理器包含不跟踪分支历史但始终选择失败路径的原始分支预测器,它开始看起来很有用。对于现代 Intel x86 硬件来说,情况并非如此。

  • 即使预测正确,未采用的分支仍然比采用的分支便宜:预测正确时不会出现任何前端气泡,并且它们可以在更多执行端口上运行(Intel Haswell)。将所有热代码放在一起对于 L1I / uop-cache 局部性 / 密度来说更好。编译器还可能根据可能或不可能的情况做出其他决定(例如,选择不让代码自动矢量化不太可能运行的循环)。或者,如果条件不太可能,则可以选择使用分支而不是“cmov”。 (3认同)