使用gcc在C ++中循环条件优化的常量嵌入

时间:2010-05-21 15:20:28

标签: c++ optimization gcc g++

编译器会优化tihs:

bool someCondition = someVeryTimeConsumingTask(/* ... */);

for (int i=0; i<HUGE_INNER_LOOP; ++i)
{
    if (someCondition)
        doCondition(i);
    else
        bacon(i);
}

成:

bool someCondition = someVeryTimeConsumingTask(/* ... */);

if (someCondition)
    for (int i=0; i<HUGE_INNER_LOOP; ++i)
        doCondition(i);
else
    for (int i=0; i<HUGE_INNER_LOOP; ++i)
        bacon(i);

someCondition在for循环中非常小。

这看起来很明显,我自己应该这样做,但如果你有多个条件,那么你正在处理for循环的permuatations,所以代码会变得更长。我决定是否这样做(我已经在优化)或是否会浪费我的时间。

3 个答案:

答案 0 :(得分:2)

使用-O2或-O3优化似乎不会这样做。这是你可以(并且如果你关心优化)你自己测试的东西 - 使用你感兴趣的优化进行编译并检查发出的汇编语言。

答案 1 :(得分:2)

编译器可能会像你一样编写代码,但我从未见过这样的优化。

然而,现代CPU中存在一种称为分支预测的东西。实质上,这意味着当要求处理器执行条件跳转时,它将在评估条件之前开始执行被判断为最可能的分支。这样做是为了使管道充满指令。

如果处理器出现故障(并接受坏分支),则会导致管道刷新:它被称为错误预测。

此功能的一个非常常见的特点是,如果相同的测试连续多次产生相同的结果,那么它将被视为通过分支预测算法产生相同的结果...当然是定制的for loops:)

这让我微笑,因为你担心if身体内的forfor本身导致分支预测&gt;&gt;必须在每次迭代时评估条件以检查是否继续;)

所以,不要担心,它的成本低于缓存未命中率。

现在,如果你真的担心这一点,总会有仿函数方法。

typedef void (*functor_t)(int);

functor_t func = 0;
if (someCondition) func = &doCondition;
else func = &bacon;

for (int i=0; i<HUGE_INNER_LOOP; ++i) (*func)(i);
确实看起来好多了,不是吗?明显的缺点是兼容签名的必要性,但您可以围绕函数编写包装器。只要你不需要打破/返回,你就可以了。否则你需要循环体中的if:D

答案 2 :(得分:0)

您有没有想过您的应用程序,以找出减速的​​位置?如果没有,为什么你甚至考虑优化?在你知道哪些方法需要优化之前,你就是在浪费时间来担心像这样的微优化。

这是减速的位置吗?如果是这样,那么你正在做的事情可能会有用。是的,编译器可以对此进行优化,但不能保证它可以。如果不是减速的位置,那么看看其他地方;每次通过循环一个额外分支的成本相对于你正在做的所有其他工作而言可能是微不足道的。