【问题标题】:In what circumstances can a compiler change the execution order of programme statements?在什么情况下编译器可以改变程序语句的执行顺序?
【发布时间】:2009-05-15 03:23:18
【问题描述】:

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

【问题讨论】:

    标签: compiler-optimization


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      一个非常简单的例子-

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

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

      不过,一个理智的编译器会看到,只有当“value”大于 10 时才需要计算“result”,因此可以轻松地将计算“value*2”移动到第一个大括号内,并且只有在以下情况下才会这样做“值”实际上大于 10(不用说,编译器在优化时不会真正查看 C 代码 - 它在较低级别工作)。

      这只是一个简单的例子。可以创建更复杂的示例。很有可能一个 C 函数最终看起来几乎与它的编译形式的 C 表示完全不同,并进行了足够积极的优化。

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2021-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-13
          • 1970-01-01
          • 1970-01-01
          • 2014-03-21
          • 1970-01-01
          相关资源
          最近更新 更多