from http://en.cppreference.com :
Relaxed ordering Atomic operations tagged std::memory_order_relaxed are not synchronization operations, they do not order memory. They only guarantee atomicity and modification order consistency. For example, with x and y initially zero,
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
is allowed to produce r1 == r2 == 42 because, although A is sequenced-before B and C is sequenced before D, nothing prevents D from appearing before A in the modification order of y, and B from appearing before C in the modification order of x.
Question: What it is the thing that confer to the above code the property A is sequenced-before B and C is sequenced before D?
EDIT:
int A, B;
void foo()
{
A = B + 1; (A)
B = 0; (B)
}
lead to
$ gcc -O2 -S -masm=intel foo.c
$ cat foo.s
...
mov eax, DWORD PTR B
mov DWORD PTR B, 0
add eax, 1
mov DWORD PTR A, eax
...
under GCC 4.6.1 with -02 option
so we clearly see that (A) and (B) have been switched
Essentially memory_order_acq_rel provides read and write orderings relative to the atomic variable, while memory_order_seq_cst provides read and write ordering globally. That is, the sequentially consistent operations are visible in the same order across all threads.
Relaxed. Relaxed accesses are the absolute weakest. They can be freely re-ordered and provide no happens-before relationship. Still, relaxed operations are still atomic. That is, they don't count as data accesses and any read-modify-write operations done to them occur atomically.
The sequenced-before (not the same as happens-before) relationships are not specific to multithreading. They happen in single threaded programs as well. Any expression that ends with a semicolon is sequenced-before the next, so in this case A
is sequenced before B
and C
before D
because each of them is a full-expression.
From the Standard 1.9 Program execution 14:
Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.
You can find an explanation here:
Order of evaluation
"Sequenced-before" applies to the visible observable behaviour of your program. The compiler is free to reach that behaviour in any way it wants; it can reorder writes to memory or eliminate them completely, as long as the visible behaviour is the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With