I'm trying to understand the instruction reordering by the following simple example:
int a;
int b;
void foo(){
a = 1;
b = 1;
}
void bar(){
while(b == 0) continue;
assert(a == 1);
}
It's known that in this example the assertion may fail if one thread executes foo, and another one executes bar. But I don't understand why. I consulted the Intel manual Vol. 3A, 8.2.2 and found the following:
Writes to memory are not reordered with other writes, with the following exceptions:
— streaming stores (writes) executed with the non-temporal move instructions (MOVNTI, MOVNTQ, MOVNTDQ, MOVNTPS, and MOVNTPD); and
— string operations (see Section 8.2.4.1).
There are no string operations here as well as I did not notice NT move instructions. So... Why is the reordering of writes possible?
Or does the memory matters in
Writes to memory are not reordered
? So when we have a and b cached and writes occur not to main memory, but to cache they can be.
aandbwill be stored in memory? There's no such requirement in C++ language, in corner case the compiler may generate code which will keep those two in registers only (for example). - Ped7ga = 1; _ReadWriteBarrier(); b = 1;on x86/x64 this will be enough - RbMmwhile(b == 0){}will become an infinite loop with any normal C compiler if it enters the loop at all. - Peter Cordes