On 03/05/17 08:30, Dietmar Schindler wrote: > The GCC Wiki says this about the memory model synchronization mode > [Acquire/Release][1]: > >> To make matters a bit more complex, the interactions of non-atomic >> variables are still the same. Any store before an atomic operation >> must be seen in other threads that synchronize. For example: >> >> | -Thread 1- >> | y = 20; >> | x.store (10, memory_order_release); >> | >> | -Thread 2- >> | if (x.load(memory_order_acquire) == 10) >> | assert (y == 20); >> >> Since 'y' is not an atomic variable, the store to 'y' _happens-before_ >> the store to 'x', so the assert cannot fail in this case. The >> optimizers must still limit the operations performed on shared memory >> variables around atomic operations. > > Now, what if I make 'y' an atomic variable (without imposing > _happens-before_ restrictions)? > > | -Thread 1- > | y.store (20, memory_order_relaxed); > | x.store (10, memory_order_release); > | > | -Thread 2- > | if (x.load(memory_order_acquire) == 10) > | assert (y.load (memory_order_relaxed) == 20); > > Can the assert fail? Are there fewer requirements for atomic variables > than for non-atomic variables? Or is the Wiki's restriction to > non-atomic variables gratuitous and misleading here? I may be completely wrong, I'm know very little about GCC, but I think the fact a variable is atomic actually makes no difference at all, as far as memory barriers are concerned. It is and only is the memory barrier which matters, when it comes to whether or not changes are propagated. Also, although I may be COMPLETELY wrong, I *think* the "atomic" store is actually just a store barrier issued after the write. If so, this to my mind is completely mis-named and by that utterly misleading, for a memory barrier imposes only *ordering* constraints. It imposes *nothing* which actually causes stores to *complete*. You can store as many times as you like, and write store barriers as often as you like; there is no guarantee any other core will ever see those stores.