我正在编写一些音频代码,基本上所有东西都是微小的循环。我理解它们的分支预测失败是一个足够大的性能问题,我很难保持代码分支免费。但是到目前为止,我才能接受,这让我想到了不同种类的分支。
在c ++中,条件分支到固定目标:
int cond_fixed(bool p) {
if (p) return 10;
return 20;
}
并且(如果我正确理解this question),无条件分支到变量目标:
struct base {
virtual int foo() = 0;
};
struct a : public base {
int foo() { return 10; }
};
struct b : public base {
int foo() { return 20; }
};
int uncond_var(base* p) {
return p->foo();
}
是否存在性能差异?在我看来,如果两种方法中的一种明显比另一种快,则编译器只需将代码转换为匹配。
对于分支预测非常重要的情况,有关性能的详细信息有用吗
编辑:x : 10 ? 20
的实际操作仅仅是占位符。分支之后的实际操作至少足够复杂,以至于两者都是低效的。此外,如果我有足够的信息来明智地使用__builtin_expect
,那么在这种情况下,分支预测将不是问题。
答案 0 :(得分:4)
旁注:如果你有像
这样的代码if (p) a = 20; else a = 10;
然后没有任何分支。编译器正在使用条件移动(请参阅:Why is a conditional move not vulnerable for Branch Prediction Failure?)
答案 1 :(得分:1)
你没有提到你的编译器。我曾经将GCC用于性能关键应用程序(实际上是我大学的比赛),我记得GCC有__builtin_expect
宏。我经历了我的代码中的所有条件,最终得到了5-10%的加速,我发现这是惊人的,因为我注意到了我所知道的几乎所有内容(内存布局等),而且我没有不改变算法本身的任何内容。
顺便提一下,算法是一个非常基本的深度搜索。我在Core 2 Duo上运行它,但不确定是哪一个。