This post is merely one condensed version of GCCMM.

Sequential Consistency

No reordering could be done by compilers for these access, and special instructions are emitted to ensure CPU would not reorder memory access, or at least provides such illusion.

Relaxed

This model allows for much less synchronization by removing the happens-before restrictions.

The relaxed mode is most commonly used when the programmer simply wants an variable to be atomic in nature rather than using it to synchronize threads for other shared memory data.

Acquire/Release

The acquire/release mode is similar to the sequentially consistent mode, except it only applies a happens-before relationship to dependent variables.

-Thread 1-
y.store (20, memory_order_release);

-Thread 2-
x.store (10, memory_order_release);

-Thread 3-
assert (y.load (memory_order_acquire) == 20 && x.load (memory_order_acquire) == 0)

-Thread 4-
assert (y.load (memory_order_acquire) == 0 && x.load (memory_order_acquire) == 10)

Both of these asserts can pass since there is no ordering imposed between the stores in thread 1 and thread 2.

If this example were written using the sequentially consistent model, then one of the stores must happen-before the other (although the order isn’t determined until run-time), the values are synchronized between threads, and if one assert passes, the other assert must therefore fail.

-Thread 1-
y = 20;
x.store (10, memory_order_release);

-Thread 2-
if (x.load(memory_order_acquire) == 10)
   assert (y == 20);

The assertion can not fail, for all the stores before release are visible after the corresponding acquire.