Memory Consistency Model

Memory Consistency Models define the contractual rules governing the order in which memory operations (loads and stores) from different threads become visible to each other — where the choice between strict sequential consistency and relaxed models (TSO, release-acquire, relaxed) determines both the correctness guarantees available to the programmer and the performance optimizations the hardware and compiler are permitted to make.

Why Consistency Models Exist

Modern processors reorder memory operations for performance: store buffers delay writes, out-of-order execution completes loads before earlier stores, and compilers rearrange memory accesses. Without a model defining which reorderings are legal, multi-threaded programs would have unpredictable behavior across different hardware.

Key Models (Strongest to Weakest)

  • Sequential Consistency (SC): All threads observe memory operations in a single total order consistent with each thread's program order. The simplest model — behaves as if one operation executes at a time, interleaved from all threads. No hardware implements pure SC efficiently because it forbids almost all reordering.
  • Total Store Ordering (TSO): Stores are delayed in a store buffer (a store may not be visible to other threads immediately), but loads always see the most recent value. The ONLY allowed reordering: a load can complete before an earlier store (to a different address) is visible. x86/x64 implements TSO — the strongest model in widespread use.
  • Release-Acquire: Acquire operations (loading a lock or flag) guarantee that all subsequent reads see values written before the corresponding release (storing the lock or flag) on another thread. Only paired acquire/release operations are ordered; other accesses may be freely reordered. C++11 `memory_order_acquire/release` implements this.
  • Relaxed (Weak Ordering): No ordering guarantees on individual loads and stores. The programmer must explicitly insert memory fences/barriers where ordering is required. ARM and RISC-V default to relaxed ordering. Maximum hardware freedom for reordering → highest performance.

Practical Impact

// Thread 1           // Thread 2
data = 42;            while (!ready);  
ready = true;         print(data);     // Must print 42?

Under SC: Guaranteed to print 42. Under Relaxed: May print 0 (stale data) because the compiler or hardware may reorder `data = 42` after `ready = true`, or Thread 2 may see `ready` before `data` propagates. Under Release-Acquire: If `ready` is stored with release and loaded with acquire, guaranteed to print 42.

Fences and Barriers

  • `__sync_synchronize()` (GCC): Full memory fence — no reordering across the fence.
  • `std::atomic_thread_fence(memory_order_seq_cst)`: Sequential consistency fence.
  • ARM `dmb` / RISC-V `fence`: Hardware memory barrier instructions.

Memory Consistency Models are the invisible contract between hardware designers and software developers — defining the boundary between optimizations the hardware may perform silently and ordering guarantees the programmer can rely upon for correct multi-threaded execution.

Take memory consistency model further

Ask the copilot about this term, or have our engineers assess it against your process.