I can't write such a program. Can you?
How would you ensure that another thread was scheduled between these instructions in order to observe some intermediate state? If I just told you the OS would never schedule between these instructions again is that breaking any contract or something you can observe somehow? How would you tell?
If we can't such a program, then the logic isn't needed.
In one thread, do a loop of:
loop:
movq [rsi], 10
addq [rsi], 5
cmpq [rsi], 15
jeq loop
(Or however you write that with correct assembler).In another thread with the same value in rsi, do:
loop:
movq [rsi], 100
jmp loop
Ensure these threads run on different cores. You would expect the loop in the first thread to eventually terminate. The probability distribution of the time it takes to terminate would probably be informative.Would it terminate on this and chip? How would the distribution be different?
The store to the address at rsi will actually go in to the processor's store buffer and the subsequent add is allowed to retrieve the value from the store buffer _before_ it's drained to main memory.
Under TSO, AMD's memory mirroring implementation here is totally fine.
It could potentially change observable behaviour if you could turn it on or off but this is irrelevant given you wil see changes in observable behaviour for that same snippet of code depending on which microarchitecture of AMD or Intel processor you choose to run it on.
It's worth having a read on the details for different memory models and how they relate to implements. This seems like a good guide: https://www.cs.utexas.edu/~bornholt/post/memory-models.html
Why would you expect it to eventually terminate? There is nothing in the architecture that should lead you to expect that.
The architecture does not guarantee that instructions from the first loop will be interleaved with the second in any particular way, no matter what cores they're running on.
> The probability distribution of the time it takes to terminate would probably be informative.
But again... the architecture does not guarantee the set of or probability of distribution of interleavings. You cannot write a sound program using this information.
while (flag1 == true && turn == 1) { /* wait */ }
the loop terminates by another thread writing to either variable.If the variables were mirrored to registers, and that mirroring was not invalidated by another thread's write, then the loop would never terminate.
Of course Zen2 did not break Peterson locks, so the GP's question is cogent and has the answer "yes, there is such logic."
Notice that your code has a backward jump between the write and the read and the example in the article (and the code of the other person I replied to) does not.
There is no logic needed to interrupt the renaming such as a signal from another core holding the cache, the rename just naturally retires beyond a certain point.
Read Morris Marden's 2014 patent on it for more details.
https://patentimages.storage.googleapis.com/16/3f/47/ea08705...
The patent is a great resource, thanks for that. But I think it supports my point when it suggests that memory renaming may persist indefinitely:
Alternatively, reclamation of the original physical register could be delayed to facilitate later memory renaming.
and later:
...the MRT may always retain physical registers of N past store operations...the physical register is reclaimed to the free list when it exits the MRT, for example, when it is no longer one of the N most recent store operations.
So it's possible. I don't think we know from Agner's work whether AMD went this route or not.
This optimization has a latency of 0-1 cycles.
It's just a guess, but that's probably what happens in order for the memory mirroring not to break the cache-coherency. So "yes, there is such logic", but it already existed in the processor to avoid the same problem when data is in the cache. And so, there would be no additional logic to handle this.
If you write memory first to address A and then to B. Another core never can see the B change without also seeing the A change at any moment in time.
But in this case there is only a single memory location. So there is no ordering that could be violated in the first place.
It's like the ABA problem - how do you differentiate between just never happening to see a B out of chance, and B being elided instead? You can't.