So, I was reading a lot about instruction and memory reordering and how we can prevent it, but i still have no answer to one qustion (probably because I'm not attentive enough). My question is: Do we have the guarantee that any atomic write will store the new value of the atomic variable in the main memory immediately? Let's take a look at a small example:
std::atomic<bool> x;
std::atomic<bool> y;
std::atomic<int> count;
void WritingValues()
{
x.store(true, std::memory_order_relaxed);
y.store(true, std::memory_order_relaxed);
}
void ReadValues()
{
while( !y.load(std::memory_order_relaxed) );
if( x.load(std::memory_order_relaxed) )
++count;
}
int main()
{
x = false;
y = false;
count = 0;
std::thread tA(WritingValues);
std::thread tB(ReadValues);
tA.join();
tB.join();
assert( count.load() != 0 );
}
So, here our assert can definitely fire, as we use std::memory_order_relaxed and do not prevent any instruction reordering (or memory reordering at compile time, i suppose that is the same thing). But if we place some compiler barrier in WritingValues to prevent instruction reordering, will everything be OK? I mean, does x.store(true, std::memory_order_relaxed) guarantees, that the write of that particular atomic variable will be directly into the memory, without any latency? Or does x.load(std::memory_order_relaxed) guarantess, that the value would be readed from the memory, not the cache with invalid value? In other words, this store guarantees only atomicity of the operation and have the same memory behaviour as usual non-atomic variable, or it also has influence on memory behaviour?
bool
s this is mostly meaningless. As far as whether other threads see the write immediately, this will forever be a mystery, because there's nothing that a thread can do to determine whether another thread has written something. That would be sequencing. I.E.: after locking a mutex a thread will see everything that another thread did before unlocking the same mutex because this is sequenced such. – Sam Varshavchik