Assuming a thread running indefinitely until it's member variable stop is set. Like
while (!stop) {
// do something
}
I want to prevent it turning into this
if (!stop) {
while (true) {
}
}
So where would I set memory barriers / fences so that this optimization can't be performed?
Also, would such a fence already be enough to ensure a change to true
from another thread is visible in the next iteration?
So where would I set memory barriers / fences so that this optimization can't be performed?
A memory barrier/fence restricts the memory ordering, which prevents the compiler from reordering two or more memory accesses in the same thread. However, memory ordering is not the issue here, as you are only talking about a single memory access per thread.
Instead, you are talking about two memory operations on the same variable from two different threads. Therefore, this is a matter of thread synchronization, not memory ordering.
According to §6.9.2.2 ¶21 of the ISO C++20 standard, if two threads access the same variable without a synchronization operation (e.g. mutex) in between, and if these memory accesses are not
then this results in undefined behavior.
Therefore, in the case of your while
loop
while (!stop) {
// do something
}
assuming that stop
is a non-atomic data type, the compiler is allowed to assume that the variable stop
will never be modified by another thread while the loop is running (unless you happen to have a synchronization operation inside the loop), because doing so would result in undefined behavior (which means that the compiler would be allowed to do anything).
For this reason, a good optimizing compiler will effectively change the code to the following:
if (!stop) {
while (true) {
// do something
}
}
However, if you change the variable stop
to an atomic data type, such as std::atomic_flag
or std::atomic<bool>
, then it is not undefined behavior for several threads to access this variable at the same time. In that case, the compiler will not be allowed to assume that stop
will not be modified by another thread, so that it will not be allowed to perform the optimization mentioned above.
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