10

我正在编写一些音频代码,基本上所有内容都是一个小循环。据我了解,分支预测失败是一个足够大的性能问题,我很难保持代码分支自由。但我只能到此为止,这让我想知道不同种类的分支。

在 c++ 中,条件分支到固定目标:

int cond_fixed(bool p) {
    if (p) return 10;
    return 20;
}

并且(如果我正确理解了这个问题),无条件分支到变量目标:

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,那么在这种情况下,分支预测将不是问题。

4

2 回答 2

4

旁注:如果您有类似的代码

if (p) a = 20; else a = 10;

然后没有任何分支。编译器正在使用条件移动(请参阅:为什么条件移动不容易受到分支预测失败的影响?

于 2014-02-13T13:28:52.457 回答
1

你没有提到你的编译器。我曾经将 GCC 用于性能关键应用程序(实际上是我大学的一场竞赛),我记得 GCC 有__builtin_expect宏。我经历了代码中的所有条件,最终得到了 5-10% 的加速,我发现这很了不起,因为我几乎关注了我所知道的一切(内存布局等)并且我没有'不要改变任何关于算法本身的东西。

顺便说一下,该算法是一个非常基本的深度搜索。我在 Core 2 Duo 上运行它,但不确定是哪个。

于 2014-02-13T13:27:32.560 回答