Quick A: No, because acq_rel
doesn't prevent reordering a store to x
followed by a load from y
... seq_cst
does.
Recently on SO:
Why isn't a C++11 acquire_release fence enough for Dekker synchronization?
The failure of Dekker-style synchronization is typically explained with reordering of instructions. I.e., if we write
atomic_int X; atomic_int Y; int r1, r2; static void t1() { X.store(1, std::memory_order_relaxed) r1 = Y.load(std::memory_order_relaxed); } static void t2() { Y.store(1, std::memory_order_relaxed) r2 = X.load(std::memory_order_relaxed); }Then the loads can be reordered with the stores, leading to
r1==r2==0
.I was expecting an acquire_release fence to prevent this kind of reordering:
static void t1() { X.store(1, std::memory_order_relaxed); atomic_thread_fence(std::memory_order_acq_rel); r1 = Y.load(std::memory_order_relaxed); } static void t2() { Y.store(1, std::memory_order_relaxed); atomic_thread_fence(std::memory_order_acq_rel); r2 = X.load(std::memory_order_relaxed); }The load cannot be moved above the fence and the store cannot be moved below the fence, and so the bad result should be prevented.
However, experiments show
r1==r2==0
can still occur. Is there a reordering-based explanation for this? Where's the flaw in my reasoning?
Add a Comment
Comments are closed.