Skip to content

memory model

serhij.zolotukhin edited this page May 21, 2026 · 2 revisions

Memory Model

The C++ Memory Model (introduced in C++11) is a formal set of rules that defines how different threads interact through shared memory. It provides a standardized "contract" between the programmer, the compiler, and the hardware, ensuring that multithreaded code behaves predictably across different platforms.

Why a Memory Model is Necessary

Before C++11, the language lacked a built-in understanding of threads. Compilers and CPUs often optimize performance by [reordering instructions] or [caching values] in ways that are invisible in a single-threaded environment but can cause ["data races"] and unpredictable results in [multithreaded code].

The memory model specifies:

  • [Visibility]: When a write to a variable by one thread becomes visible to another.
  • [Ordering]: Which instructions can be reordered and which must stay in sequence.

Core Components

The memory model is built on three main pillars:

  • [Atomic Operations] (std::atomic)Atomic operations are indivisible—no thread can see the operation in a "half-finished" state. They are the building blocks of thread-safe communication without using heavy locks like mutexes. Use the std::atomic documentation to explore available types.

  • [Memory Ordering Constraints] You can specify how strictly the compiler and CPU must order memory accesses. The most common types available via std::memory_order include:

  • Sequential Consistency (memory_order_seq_cst): The strictest and default mode. It guarantees that all threads see memory operations in the exact same global order.

  • Acquire-Release (memory_order_acquire, memory_order_release): A middle ground where a thread "releasing" a variable synchronizes specifically with a thread "acquiring" it.

  • Relaxed (memory_order_relaxed): No synchronization or ordering; only guarantees the operation itself is atomic.

  • The ["Happens-Before"] Relationship

This is the mathematical foundation of the model. If operation (A) "happens-before" operation (B), then (A) is guaranteed to be visible to (B). If two threads access the same memory and neither access "happens-before" the other (and at least one is a write), a Data Race occurs, which results in Undefined Behavior.

Key Benefits

  • Portability: Code written following the C++ memory model will work correctly on both "strong" hardware like x86 and "weak" hardware like ARM.
  • Performance: By allowing "relaxed" or "acquire-release" ordering, experts can write high-performance, lock-free algorithms that avoid the overhead of full sequential consistency.
  • Tooling Support: Tools like CppMem allow developers to mathematically verify if their concurrent code is race-free.

https://www.geeksforgeeks.org/cpp/memory-model-in-cpp-11/

My side bar

Clone this wiki locally