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