I am working on a multithreded algorithm which reads two shared atomic variables:
std::atomic<int> a(10);
std::atomic<int> b(20);
void func(int key) {
int b_local = b;
int a_local = a;
/* Some Operations on a & b*/
}
The invariant of the algorithm is that b
should be read before reading a
.
The question is, can compiler(say GCC) re-order the instructions so that a
is read before b
? Using explicit memory fences would achieve this but what I want to understand is, can two atomic loads be re-ordered.
Further, after going through Acquire/Release semantics from Herb Sutter's talk(http://herbsutter.com/2013/02/11/atomic-weapons-the-c-memory-model-and-modern-hardware/), I understand that a sequentially consistent system ensures an ordering between acquire(like load) and release(like store). How about ordering between two acquires(like two loads)?
Edit: Adding more info about the code: Consider two threads T1 & T2 executing:
T1 : reads value of b
, sleeps
T2 : changes value of a
, returns
T1 : wakes up and reads the new value of a
(new value)
Now, consider this scenario with re-ordering:
int a_local =a;
int b_local = b;
T1 : reads value of a
, sleeps
T2 : changes value of a
, returns
T1 : Doesn't know any thing about change in value of a
.
The question is "Can a compiler like GCC re-order two atomic loads`