The memory ordering guarantees across different memory regions on x86 architectures are not clear to me. Specifically, the Intel manual states that WC, WB and UC follow different memory orderings as follows.
WC: weak ordering (where e.g. two stores on different locations can be reordered)
WB (as well as WT and WP, i.e. all cacheable memory types): processor ordering (a.k.a TSO, where younger loads can be reordered before older stores on different locations)
UC: strong ordering (where all instructions are executed in the program order and cannot be reordered)
What is not clear to me is the interaction between UC and the other regions. Specifically, the manual mentions:
(A) UC accesses are strongly ordered in that they are always executed in program order and cannot be reordered; and
(B) WC accesses are weakly-ordered and can thus be reordered.
So between (A) and (B) it is not clear how UC accesses and WC/WB accesses are ordered w.r.t. one another.
1a) [UC-store/WC-store ordering] For instance, let us assume that x is in UC memory and y is WC memory. Then in the multi-threaded program below, is it possible to load 1 from y and 0 from x? This would be possible if the two stores in thread 0 can be reordered. (I have put an mfence
between the two loads hoping that it would stop the loads from being reordered, as it is not clear to me whether WC/UC loads can be reordered; see 3a below)
thread 0 | thread 1 store [x] <-- 1 | load [y]; mfence store [y] <-- 1 | load [x]
1b) What if instead (symmetrically) x were in WC memory and y were in UC memory?
2a) [UC-store/WB-load ordering] Similarly, can a UC-store and a WB-load (on different locations) be reordered? Let us assume that x is in UC memory and z is in WB memory. Then in the multi-threaded program below, is it possible for both loads to load 0? This would be possible if both x and z were in WB emory due to store buffering (or alternatively justified as: younger loads in each thread can be reordered before the older stores as they are on different locations). But since the accesses on x are in UC memory, it is not clear whether such behaviours are possible.
thread 0 | thread 1 store [x] <-- 1 | store [z] <-- 1 load [z] | load [x]
2b) [UC-store/WC-load ordering] What if z were in WC memory (and x is in UC memory)? Can both loads load 0 then?
3a) [UC-load/WC-load ordering] Can a UC-load and a WC-load be reordered? Once again, let us assume that x is in UC memory and y is in WC memory. Then, in the multi-threaded program below, is it possible to load 1 from y and 0 from x? This would be possible if the two loads could be reordered (I believe the two stores cannot be reordered due to the intervening sfence
; the sfence
may not be needed depending on the answer to 1a).
thread 0 | thread 1 store [x] <-- 1; sfence | load [y] store [y] <-- 1 | load [x]
3b) What if instead (symmetrically) x were in WC memory and y were in UC memory?
4a) [WB-load/WC-load ordering] What if in the example of 3a above x were in WB memory (instead of UC) and y were in WC memory (as before)?
4b) What if (symmetrically) x were in WC memory and y were in WB memory?
https://stackoverflow.com/questions/66978388/intel-x86the-interaction-between-wc-wb-and-uc-memory April 07, 2021 at 09:24AM
没有评论:
发表评论