编译器,If语句和循环

时间:2014-06-27 03:52:44

标签: c++ performance compiler-construction

这是c ++的一般效率问题。我不熟悉编译器的内部工作原理,所以假设我有几个循环和一个潜在的if语句,例如:

for(int i=0; ...) 
{
    for(int j=0; ...)
    { 
        if( ... )
        {
            ...
        }
        else
        {
            ... (slightly different)
        }
    }
}

但是,这个if语句独立于循环。如果我在循环外部用循环定义if / else语句,是否存在明显的速度差异? E.g:

if( ... )
{
    for(int i=0; ...) 
    {
        for(int j=0; ...)
        { 
            ...
        }
    }
}
else
{
    for(int i=0; ...) 
    {
        for(int j=0; ...)
        { 
            ... (slightly different)
        }
    }
}

如果是这样,或者如果不是,那为什么呢?我有一些想法,编译器会认识到相同的if语句一遍又一遍地完成,但这对我来说是非常陌生的领域。

我检查了对这个问题的回答: Would compiler optimize conditional statement in loop by moving it ouside the loop? 他讨论了gcc中不同级别的优化,以及-O3(我认为)如何做到这一点。但是这样做会自动完成吗?如果没有,那么在循环内部if语句的成本有多大?

3 个答案:

答案 0 :(得分:2)

这个问题不可能说哪个更快。

记住80-20规则(http://en.wikipedia.org/wiki/Pareto_principle#In_software)并通过分析找到一些代码。

无论如何,只需编写可读和可维护的代码。如果您遇到性能问题,请查看代码。

答案 1 :(得分:2)

取决于案例,但我敢打赌第二种选择更快。这是因为不会发生分支,编译器有更多机会用一些MMX / SSE指令组替换大量代码。

至少在理论上,在第一种情况下,CPU必须在每个for()循环中解决相同的if()。在第二种情况下if()在外观之外并且应该更快。但同样,现代编译器经常可以找到这个问题并神奇地解决它。

但是,是的,通常编写代码以提高可读性非常重要,除非性能是真正的重要问题。

答案 2 :(得分:2)

唯一真正的答案可能是。如果条件是循环 不变,那么你建议的换位是合法的,如果 编译器可以识别循环不变性,然后就可以了 换位。是否它取决于 编译器:g++ /O3至少在64位模式下cl /Ox /Os 没有,至少在32位模式下; g ++还展开了两个循环。 在我的测试中,至少;我或多或少保证了 编译器可以确定条件是循环不变量 通过使用条件将循环包装在函数中 类型为bool const的函数参数;取决于 条件,编译器可能或多或少有困难 证明循环不变性。当然,这个事实 编译器有更多的寄存器可以在64位模式下播放 也会影响其优化。

另外:虽然我本能地期待g ++版本 更快,它显着更大;在某些情况下,这可能 负面影响各种内存缓存,导致 代码实际运行速度较慢。

最后,我总是写第一个。如果探查器以后 表明它是一个瓶颈,回头路没有问题 并沿着第二行重写,然后测量 看看它是否有所作为,不管怎么样,以及如何 它有很大的不同。并注意最好的结果 可能取决于您的编译器和架构 打靶。