Your example is simply wrong.syzygy wrote:Look. I gave an example, which you acknowledge, where the value read is NOT the LAST value written by any other CPU.bob wrote:Sorry it is absolutely correct. Just look up their MESIF cache coherency protocol, it will explain EXACTLY why it is guaranteed to be true. That is the very definition of "cache coherent NUMA"syzygy wrote:This is what you wrote:bob wrote:That is a trivial example that is well known. Has absolutely nothing to do with current discussion which would only be about ONE variable. You will NEVER get an old value with Intel.syzygy wrote:I was wrong to say that Intel guarantees the illusion that a read will always give the last value written by any other CPU. Not even this illusion holds true in its full generality.bob wrote:It is NOT ok to retrieve old values. The caches on Intel SPECIFICALLY prevent this by their snooping and inter-cache forwarding. Where is this stuff coming from? On Intel, the value you read will be the LAST value written by any other CPU. That's guaranteed.
Suppose memory locations x and y are initialised to 0.
Now CPU1 performs a write and a read:
mov $1, [x]
mov [y], %eax
At roughly the same time, CPU2 also performs a write and a read:
mov $1, [y]
mov [x], %eax
Now %eax for both CPU1 and CPU2 may be 0.
How can that be? If CPU1 reads 0 from [y], it must have executed the read before CPU2 executed the write, right? So CPU1 must have executed the write even earlier, and CPU2 must have executed the read even later. That means that CPU2 can only have read 1. But in reality, it may read a 0.It is wrong.bob wrote:On Intel, the value you read will be the LAST value written by any other CPU. That's guaranteed.
The value read is 0. At the time the value is being read, the value 1 had already been written. Capisce?
When ANY core writes to a variable, it is INSTANTLY invalidated in all other caches. There is absolutely no way another CPU can get an old value after that, because the cache has to do another read from memory since it no longer has that value. The cache with the newly modified data will forward a copy to the requestor, the requestor ends up with the last value written. Happens that way every last time. If a cpu does a read BEFORE a value is modified, certainly it will get the old value. If it reads the value AFTER another core has written to that address it will NEVER get the old value.
So what, exactly, are you talking about? This is an actual guarantee by the cache coherency protocol. Please give a sensible example. In your case, you are depending on a race. A race where the last write is NOT done last. I don't care about that case. Whenever the write is done, from that point on everyone will get the new value, IF they do a read after the write. If they did a read before the write, they get the old value. If they do ANOTHER read after the write, they get the new value.
Your example is not doing reads/writes to the SAME value...