Reputation: 1401
I'm trying to understand the coherency guarantees in C++ on a x86-64 machine, and if that varies on other platforms. Specifically I'm wondering if I can guarantee that if one thread writes to a variable before the next thread reads from it, will I always see the correct value? I've read some conflicting information about this.
Here's an example, where Shared
is updated in another thread, and the result is read only when we're sure the value is finished being updated. Will this always print 1? It has every time I tested it, but I can't really prove it by example.
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<bool> Done {false};
int Shared = 0;
int main(int argc, const char* argv[])
{
auto Thread = std::thread([](){
Shared = 1;
Done = true;
});
while(!Done)
{
}
std::cout << Shared << std::endl;
Thread.join();
return 0;
}
This blog seems to suggest that on x86-64 all writes are made visible to other threads: http://benbowen.blog/post/cmmics_iii/
This document also sounds like it's saying something similar:
When a thread is writing to a shared memory location, the MESIF protocol requires that all other copies of the memory location is invalidated. If this occurs, all cores in the processor sends a RFOrequest (readforownership request) to the LLC (in this case the L3cache) that checks the snoopfilter and then sends out invalidations to all cache’s that holds a copy of the cache line.
https://www.eit.lth.se/fileadmin/eit/courses/edt621/Rapporter/2015/robin.skafte.pdf
Upvotes: 5
Views: 814
Reputation: 16355
It's complicated, but in your particular case, this is guaranteed to work across all C++ implementations.
The reason is that the default memory order for operations on std::atomic
is std::memory_order_seq_cst
, which does guarantee release/acquire semantics.
Specifically, that means that any writes that a thread makes to memory before it release-stores (including sequentially consistent stores, like yours) are visible to any thread that acquire-loads on the same atomic (including sequentially consistent loads, like yours) and observes the new value.
Upvotes: 4