I have read the doc of std::memory_order_relaxed.
One part of explanation of Relaxed ordering is ....
// 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
and the explanation of this is said ...
[It] is allowed to produce
r1 == r2 == 42
. In particular, this may occur if D is completed before C in thread 2, either due to compiler reordering or at runtime.
I have understood the explanation, and try to test on my computer as following code:
std::atomic<int> x = {0};
std::atomic<int> y = {0};
int r1, r2;
void task1() {
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
}
void task2() {
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
}
int main()
{
std::thread t2 (task2);
std::thread t1 (task1);
t1.join();
t2.join();
cout << "r1: " << r1
<< "\nr2: " << r2 << endl;
return 0;
}
The results of this code is never r1 == r2 == 42
, which is said that it's a possible behavior in that doc.
Is there any wrong in this code? Or, is there any misunderstanding?
Or, is there any misunderstanding?
Yes there is one. What std::memory_order_relaxed
allows in your program is for an implementation (a compiler) targeting an architecture, to produce a program which may observe the side effect r1 == r2 == 42
.
An implementation does not have to produce such a program, and such a program does not have to produce that side effect; it is a possible outcome anyway.
How to test the behavior of std::memory_order_relaxed?
I cannot see a general solution to this question. You can only check that the side effect you observes matches with the specs of std::memory_order_relaxed
.
Your code is a bit naive because by the time the 2nd thread starts the 1st one may have completed. The threads need to run these pieces of code truly concurrently.
For r1 == r2 == 42
to be true it requires load C
to be reordered past store D
, x86 does not do loads reordered after stores currently, so that you may never observe this kind of reordering on this platform (unless the compiler reorders C
with D
).
ARM and PowerPC, on the other hand, have weaker memory models. See Runtime memory ordering table.
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