1

我一直在阅读关于优化代码中代码执行保证的很多关于 SO 的问题,所以我试图编译一个关于允许/阻止编译器重新排序代码序列的原因列表。

我已经从通常正确的答案开始,但我没有从标准中添加引号(这是根据我的经验得出的)。如果有任何被遗忘或扩展/更正的内容,我会要求您添加到提供的答案中。

另外,有人可以为我验证代码块是否不需要重新排序。IE

void fn()
{
  { /* code block 1 */ ... }
  { /* code block 2 */ ... }
}

代码是否可以code block 1混合之前执行code block 2

4

2 回答 2

6

该标准为编译器重新排序代码和进行各种其他优化提供了很大的余地。对优化器的唯一真正约束是执行代码的可观察结果应该“好像”代码是按照程序员编写的顺序执行的。只要遵循“好像”规则,编译器/链接器/CPU/内存子系统就可以自由地重新排序他们喜欢的任何东西。变量上的 volatile 修饰符限制了对该变量进行重新排序(或省略)读取和写入的机会,因为它告诉编译器它不能对变量的状态从一次读取或写入到另一个进行任何假设,但它通常不会影响在同一段代码中对其他非易失性变量的读取和写入。

C++11 标准添加了额外的语言,明确说明了在事情更复杂的多线程世界中存在哪些保证。在这里,该标准保证“无数据竞争程序的顺序一致性”。如果程序员使用正确的同步并且不编写任何数据竞争,这实际上是“好像”规则。但是,如果您的代码存在数据竞争,那么您可能会观察到如果代码按照您编写的顺序执行时可能出现的结果,而同时存在多个同时执行的线程。C++11 原子和内存屏障提供了向编译器表达附加约束的方法,即在存在多个同时执行线程的情况下可以安全地执行哪些类型的重新排序。

于 2013-06-26T20:31:17.090 回答
-2

Code reordering relative to other code can happen if:

  1. Code executed is orthogonal to code sequences surrounding it (is not dependent on previous code or is dependent on by future code).

Code cannot be reordered if:

  1. Information as to what the code will modify is not available to the compiler. I.e. calling a function who's declaration is available but not a definition.
  2. Access to volatile variables require that they must not be reordered w.r.t. each other (but also has the additional constraint that their values are not cached by the compiler but possibly may be cached by hardware).
于 2013-06-26T19:36:08.137 回答