Memory Models & Atomics

a memory fence / barrier (atomic_thread_fence)

/ fence -> fents /

A fence is a standalone ordering instruction — a 'no operation reorders across this line' marker you place in the instruction stream. Unlike an atomic load or store, a fence does not read or write any value; it touches no location. It only constrains how the operations BEFORE it and AFTER it may be reordered relative to one another, by the compiler and by the CPU.

You write atomic_thread_fence(memory_order order) in C (or std::atomic_thread_fence in C++, std::sync::atomic::fence in Rust). The order tag picks the flavour: a release fence stops earlier memory operations from sinking past it; an acquire fence stops later memory operations from rising above it; a seq_cst fence is a full barrier in both directions. The key difference from an atomic operation is the separation of duties: with a release STORE, the ordering and the publish-the-value happen together; with a release FENCE plus a later relaxed store, you can place the barrier once and then do several cheap relaxed stores, or order operations that are not themselves on the atomic. Fences are coarser and sometimes cheaper or more flexible than tagging each access.

When do you actually need one? Rarely, in honest practice — a release store paired with an acquire load covers almost every case more clearly. Fences earn their keep in a few spots: pairing a relaxed store with a separate release fence in a tight loop, interacting with memory-mapped device registers, or matching the exact barrier a specific algorithm's proof requires. The standard caution: a fence orders nothing by itself across threads; it only takes effect when it pairs with another thread's fence or atomic operation through a happens-before relationship, exactly like release/acquire.

data = 99; atomic_thread_fence(memory_order_release); atomic_store_explicit(&ready, 1, memory_order_relaxed); /* relaxed store, but the fence orders 'data' before it */

A release fence lets a cheap relaxed store publish data; the reader needs a matching acquire fence after its relaxed load.

A fence is NOT itself atomic and reads/writes nothing — do not confuse it with a memory barrier instruction's hardware cost; and a lone fence, like a lone release, synchronizes with nothing until something on another thread pairs with it.

Also called
memory barrieratomic_thread_fence記憶體柵欄