便携式分支预测提示

2021-12-20 00:00:00 optimization c c++ branch-prediction c++20

是否有任何可移植的方式进行分支预测提示?考虑以下示例:

Is there any portable way of doing branch prediction hints? Consider the following example:

  if (unlikely_condition) {
    /* ..A.. */
  } else {
    /* ..B.. */
  }

这与做有什么不同吗:

  if (!unlikely_condition) {
    /* ..B.. */
  } else {
    /* ..A.. */
  }

或者是使用编译器特定提示的唯一方法?(例如 GCC 上的 __builtin_expect)

Or is the only way to use compiler specific hints? (e.g. __builtin_expect on GCC)

编译器是否会根据条件的顺序对 if 条件进行任何不同的处理?

Will compilers treat the if conditions any differently based on the ordering of the conditions?

推荐答案

进行静态分支预测的规范方法是 if 被预测为非分支(即每个 if> 子句被执行,而不是 else),并采用循环和向后goto.因此,如果您希望静态预测很重要,请不要将常见情况放在 else 中.绕过一个未采取的循环并不容易.我从来没有尝试过,但我想把它放在一个 else 子句中应该可以很好地移植.

The canonical way to do static branch prediction is that if is predicted not-branched (i.e. every if clause is executed, not else), and loops and backward-gotos are taken. So, don't put the common case in else if you expect static prediction to be significant. Getting around an untaken loop isn't as easy; I've never tried but I suppose putting it an an else clause should work pretty portably.

许多编译器支持某种形式的#pragma unroll,但仍然需要用某种#if来保护它以保护其他编译器.

Many compilers support some form of #pragma unroll, but it will still be necessary to guard it with some kind of #if to protect other compilers.

分支预测提示理论上可以表达一个完整的描述如何转换程序的流程控制图和如何排列可执行内存中的基本块……所以有各种各样的东西要表达,而且大多数不会很便携.

Branch prediction hints can theoretically express a complete description of how to transform a program's flow-control graph and arrange the basic blocks in executable memory… so there are a variety of things to express, and most won't be very portable.

正如 GNU 在 __builtin_expect 的文档中所推荐的那样,配置文件引导的优化优于提示,而且工作量更少.

As GNU recommends in the documentation for __builtin_expect, profile-guided optimization is superior to hints, and with less effort.

相关文章