The C++ Memory Model

Learn about the C++ memory model, including instruction reordering and the use of atomics and memory orders.

Why are we talking about the memory model of C++ in a chapter about concurrency? The memory model is closely related to concurrency since it defines how the reads and writes to the memory should be visible among threads. This is a rather complicated subject that touches on both compiler optimizations and multicore computer architecture. The good news, though, is that if our program is free from data races and we use the memory order that the atomics library provides by default, our concurrent program will behave according to an intuitive memory model that is easy to understand. Still, it is important to at least understand what the memory model is and what the default memory order guarantees.

Instruction reordering

To understand the importance of the memory model, we first need some background about how the programs we write are actually executed.

When we write and run a program, it would be reasonable to assume that the instructions in the source code will be executed in the same order as they appear in the source code. This is not true. The code we write will be optimized in multiple stages before it is finally executed. Both the compiler and the hardware will reorder instructions to execute the program more efficiently. This is not new technology: compilers have done this for a long time, and this is one reason why an optimized build runs faster than a non-optimized build. The compiler (and hardware) are free to reorder instructions as long as the reordering is not observable when running the program. The program runs as if everything happens in program order.

Let’s look at an example code snippet:

Get hands-on with 1200+ tech skills courses.