At what point is code reordering in C++ optimization stopped?
Asked Answered
H

2

1

I've been reading quite a few question on SO regarding code execution guarantees in optimised code, so I'm trying to compile a list of reasons as to what allows/stops the compiler from reordering code sequence.

I've start the answer with what is generally true but I've not added quotes from the standard (this was taken from my experience). I would ask that you add to the answer provided if there is anything that was forgotten or expand/correct on points that are there.

Also, can someone verify for me if 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 to mingle or be executed prior to code block 2?

Haemachrome answered 26/6, 2013 at 19:36 Comment(3)
Much of the optimization process isn't done on C++ statements but on assembly instructions or some compiler specific internal representation. At this level there is no concept of C++ blocks (or even individual statements) so the optimizer can certainly rearrange things across blocks.Wooden
Which compiler? Optimizer? Version? What compiler flags?Crystallography
@Crystallography I'm talking in general, given the standard what is allowed.Haemachrome
R
6

The standard gives a lot of leeway to the compiler to reorder code and do all kinds of other optimizations. The only real constraint placed on the optimizer is that the observable results of executing the code should be 'as if' the code was executed in the order written by the programmer. The compiler / linker / CPU / memory subsystem are free to reorder anything they like as long as the 'as if' rule is followed. The volatile modifier on a variable limits the opportunities for reordering (or eliding) reads and writes to that variable since it tells the compiler that it can't make any assumptions about the state of the variable from one read or write to another but it generally doesn't affect reads and writes to other non-volatile variables in the same piece of code.

The C++11 standard adds additional language clarifying exactly what guarantees exist in a multi-threaded world where things are a bit more complex. Here, the standard guarantees 'sequential consistency for data-race free programs'. This is really the 'as if' rule provided the programmer uses correct synchronization and doesn't write any data races. If your code has a data race however you may be able to observe results that would not be possible if the code was executed in the order you wrote it when there are multiple simultaneous threads of execution. The C++11 atomics and memory barriers provide means to express additional constraints to the compiler on what kinds of reordering can be safely performed in the presence of multiple simultaneous threads of execution.

Rockribbed answered 26/6, 2013 at 20:31 Comment(0)
H
-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).
Haemachrome answered 26/6, 2013 at 19:36 Comment(3)
Instead of downvoting without stating what is wrong, fix it. Or downvote with a reason.Haemachrome
I didn't downvote, but the problem with the answer is that it doesn't really reference any C++ definitions. For example, you are correct that volatile variables cannot be reordered but don't explain why. (The reason is that reads and writes to volatile variables are observable, and the compiler can do anything as long as the observable behavior is the same.) But then go on to talk about caching, which has nothing to do with what C++ allows to be reordered (which again is anything, as long as what we observe doesn't change). The other answer does talk about these C++ concepts.Oenone
Also perhaps a bit more "cultural", self-answered questions are generally expected to be of very high quality; that is long and though-out with strong references and reasoning. Someone who might normally just ignore a lower-quality answer might be more compelled to downvote if you self-answered. See my previous comment for why someone might consider this a low-quality answer.Oenone

© 2022 - 2024 — McMap. All rights reserved.