不要糊弄分支预测器
为了避免流水线阻塞,最好是没有任何分支结构。遗憾的是编程中不可能不用分支,退而求其次,我们能做的是尽量减少分支。一个经典的减少分支的办法是用位操作取代条件表达式,像这样:
const int maxValue = 16;
if (x >= maxValue) x = 0;
// 等同于
x = (x + 1) & (maxValue - 1);
我想我们应当承认,这都是些丑陋的底层优化技巧,最好留在微调优化的阶段或者干脆留给编译器。另一个这种类型的技术是循环展开。另一个更为实用的技术是帮助编译器产生更多有利于分支预测的代码,例如Linux内核中使用宏: likely()和unlikely(), 这两者都使用了GCC编译器的__builtin_expect()预处理指令。通常认为这个预处理指令支持分支预测,它允许编译器对代码进行重新组织,使各种优化成为可能。然而,在老的采用静态分支预测的处理器架构中,使用特殊的指令前缀表示其分支是否有较大可能被执行;但对于采用动态分支预测的新处理器架构,这些指令前缀将被忽略,不产生任何效果。
由此可以得到一个结论:即随着分支预测器本身越来越好,我们只有在非常少量的情况下才需要去手动干预它们。只有一件事情我们必须谨记:分支预测器的跳转表尺寸有限(较小),不要浪费!总结:不要过多地使用分支,维持良好的代码局部性!
网友评论