memory consistency model
**Memory Consistency Models** define the **formal rules governing the order in which memory operations (loads and stores) from different threads or processors appear to execute**, establishing the contract between hardware and software about what orderings are possible when multiple threads access shared memory. Understanding consistency models is essential for writing correct concurrent programs and designing efficient parallel hardware.
**Coherence vs. Consistency**: Cache **coherence** ensures that all processors see the same value for a single memory location (single-writer/multiple-reader invariant). Memory **consistency** governs the ordering of operations across different memory locations — a much more complex problem. A system can be coherent but have relaxed consistency.
**Consistency Model Hierarchy** (from strictest to most relaxed):
| Model | Ordering Guarantee | Performance | Used By |
|-------|-------------------|-------------|----------|
| **Sequential Consistency** | All ops appear in some total order | Slowest | Theoretical ideal |
| **TSO (Total Store Order)** | Store-Store, Load-Load ordered | Good | x86, SPARC |
| **Relaxed** (ARM, RISC-V) | Few guarantees without fences | Best | ARM, RISC-V, POWER |
| **Release Consistency** | Sync ops enforce order | Best | Acquire/Release semantics |
**Sequential Consistency (SC)**: Lamport's definition — the result of execution appears as if all operations were executed in some sequential order, and operations of each processor appear in program order. SC is intuitive but expensive: it prevents hardware optimizations like store buffers, out-of-order execution past memory ops, and write coalescing.
**Total Store Order (TSO)**: Used by x86. Relaxes SC by allowing a processor to read its own store before it becomes visible to others (store buffer forwarding). Stores from different processors still appear in a single total order. Most programs written assuming SC work correctly under TSO because the only relaxation is store-to-load reordering, which rarely affects algorithm correctness.
**ARM/RISC-V Relaxed Models**: Provide minimal ordering guarantees by default — loads and stores can be reordered freely (load-load, load-store, store-store, store-load all permitted). Programmers must insert explicit **fence/barrier instructions** to enforce ordering: **DMB** (data memory barrier) on ARM, **fence** on RISC-V. This maximally enables hardware optimizations but requires careful use of barriers in concurrent algorithms.
**Acquire/Release Semantics**: A practical middle ground used by C++11 memory model: **acquire** loads prevent subsequent operations from being reordered before the load; **release** stores prevent preceding operations from being reordered after the store. Together, acquire-release pairs create happens-before relationships sufficient for most synchronization patterns (mutexes, spin locks) without requiring full sequential consistency.
**Programming Implications**: On relaxed architectures, failing to use proper fences/atomics leads to subtle bugs: message-passing idioms (flag-based signaling) may fail because the flag write can be observed before the data write; double-checked locking without proper memory ordering leads to using uninitialized objects.
**Memory consistency models are the invisible contract that makes parallel programming possible — they define what correct means for shared-memory concurrent programs, and misunderstanding them is the root cause of some of the most difficult-to-diagnose bugs in concurrent software.**