在什么情况下编译器可以更改程序语句的执行顺序?

时间:2009-05-15 03:23:18

标签: compiler-optimization

如果是not a real question,请随时关闭;)

3 个答案:

答案 0 :(得分:9)

不仅编译器可以重新排序执行(主要用于优化),大多数现代处理器也这样做。阅读有关执行重新排序和memory barriers的更多信息。

答案 1 :(得分:5)

当编译认为适合于优化目的时,编译器可以更改语句的执行顺序,并且当这些更改不会改变代码的可观察行为时。

一个非常简单的例子 -

int func (int value)
{
    int result = value*2;
    if (value > 10)
    {
       return result;
    }
    else
    {
       return 0;
    }
}

一个天真的编译器可以按照所示的顺序为此生成代码。首先计算“结果”并仅在原始值大于10时返回(如果不是,则“结果”将被忽略 - 不必要地计算)。

但是,一个理智的编译器会发现只有当“value”大于10时才需要计算“result”,所以可以很容易地在第一个括号内移动计算“value * 2”,只有在“value”实际上大于10(不用说,编译器在优化时不会真正查看C代码 - 它在较低级别工作)。

这只是一个简单的例子。可以创建更复杂的示例。很可能C函数最终看起来几乎没有像编译形式的C表示那样,具有足够的积极优化。

答案 2 :(得分:4)

许多编译器使用称为“公共子表达式消除”的东西。例如,如果您有以下代码:

for(int i=0; i<100; i++) {
    x += y * i * 15;
}

编译器会注意到y * 15是不变的(其值不会改变)。因此它会计算y * ​​15,将结果粘贴到寄存器中并将循环语句更改为“x + = r0 * i”。这是一个人为的例子,但在使用数组索引或任何其他基本+偏移类型的情况时,你经常会看到这样的表达式。