At what point did the reordering of code in C ++ optimization stop?

I read quite a few questions about SO about guarantees of code execution in optimized code, so I am trying to compile a list of reasons that the compiler allows / stops the code sequence from being reordered.

I started the answer with what is generally true, but I did not add a quote from the standard (this was taken from my experience). I would ask you to add an answer if there is something that has been forgotten, or expand / correct the points that are there.

In addition, someone can check me if the code blocks are not subject to reordering. I.e.

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

Is it possible for code in code block 1 mix or execute before code block 2 ?

+2
source share
2 answers

The standard provides many opportunities for the compiler to reorder code and perform all sorts of other optimizations. The only real restriction imposed on the optimizer is that the observable results of code execution should be โ€œas ifโ€, the code was executed in the order written by the programmer. The compiler / linker / processor / memory subsystem can freely reorder whatever they like if the โ€œas ifโ€ rule applies. The volatile modifier on a variable limits the reordering (or return) possibilities for reading and writing to this variable, since it tells the compiler that it cannot make any assumptions about the state of the variable from one read or write to another, but usually does not affect reading and writing to other non-volatile variables in the same code fragment.

The C ++ 11 standard adds an additional language that clearly explains what guarantees exist in a multi-threaded world where the situation is a bit more complicated. Here, the standard guarantees consistent consistency for free data transfer programs. This is really an โ€œas ifโ€ rule if the programmer uses the correct synchronization and does not write any data calculations. If your code has a data race, you can observe results that would not be possible if the code were executed in the order in which you wrote it when there are several simultaneous threads of execution. The Atomics and Memory Layer C ++ 11 provides a means for expressing additional constraints for the compiler about what types of reordering can safely be performed if there are several simultaneous execution threads.

+5
source

A reordering of the code relative to another code can occur if:

  • The executed code is orthogonal to the code sequences surrounding it (does not depend on the previous code or depends on the future code).

The code cannot be reordered if:

  • Information about which code will be changed is not available to the compiler. That is, a function call whose declaration is available, but not a definition.
  • Access to volatile variables requires that they not be reordered by wrt (but also has the additional restriction that their values โ€‹โ€‹are not cached by the compiler, but may possibly be cached by hardware).
-1
source

Source: https://habr.com/ru/post/976237/


All Articles