memory consistency model
**Memory Consistency Models** are the **formal specifications that define the order in which memory operations (loads and stores) from different threads or processors become visible to each other — determining what values a parallel program can legally observe when multiple threads access shared memory, and directly impacting both the correctness of lock-free algorithms and the performance optimizations that hardware and compilers can apply**.
**Why Consistency Models Matter**
Modern processors execute instructions out of order, maintain store buffers, and use multi-level cache hierarchies. Without a consistency model, a store by Thread A might become visible to Thread B at an unpredictable time, making concurrent programming impossible. The consistency model is the contract between hardware and software that defines what reorderings are allowed.
**Key Consistency Models (Strictest to Most Relaxed)**
- **Sequential Consistency (SC)**: The result of any execution is the same as if all operations from all threads were interleaved in some sequential order, consistent with each thread's program order. The gold standard for programmability but prohibitively expensive — it prevents most hardware store buffer and cache optimizations.
- **Total Store Order (TSO)**: Used by x86. A store may be delayed in the store buffer (appearing to be reordered after subsequent loads by the same thread), but all stores become globally visible in program order. Most programs "just work" on TSO without explicit fences.
- **Relaxed (Weak) Ordering**: Used by ARM and RISC-V. Loads and stores can be reordered freely unless explicit memory barriers (fences) constrain the ordering. Maximum hardware optimization freedom but requires the programmer to insert barriers at synchronization points.
- **Release Consistency**: A refinement of relaxed ordering. Acquire operations (lock, load-acquire) prevent subsequent operations from being reordered before the acquire. Release operations (unlock, store-release) prevent preceding operations from being reordered after the release. Synchronization points define the ordering boundaries.
**Memory Barriers (Fences)**
On relaxed architectures, the programmer inserts explicit fence instructions to enforce ordering:
- **Store-Store Fence**: All stores before the fence become visible before any store after the fence.
- **Load-Load Fence**: All loads before the fence complete before any load after the fence.
- **Full Fence**: Orders all memory operations in both directions.
In C/C++, std::atomic operations with memory_order_acquire, memory_order_release, and memory_order_seq_cst map to the appropriate hardware fences.
**Impact on Lock-Free Programming**
Lock-free data structures (queues, stacks, hash maps) rely on specific memory ordering to ensure that one thread's publications (data writes followed by a flag write) are seen in the correct order by consuming threads. A missing fence on a relaxed architecture can cause a consumer to read the flag (published) but see stale data — a bug that may manifest only once per million operations and only on ARM, not x86.
**Performance Implications**
Stricter models constrain hardware optimizations, reducing IPC. The shift from x86 (TSO) to ARM (relaxed) in data centers forces careful audit of all lock-free code and synchronization patterns. Libraries like Java's java.util.concurrent and C++ atomics abstract the model differences, but understanding the underlying model is essential for performance-critical code.
Memory Consistency Models are **the hidden contract between hardware and software that makes shared-memory parallel programming possible** — defining the rules by which stores become visible across threads, and determining whether a clever lock-free algorithm is correct or contains a race condition that surfaces only on certain architectures.