The pre-knowledge is here.
Here’s a question on StackOverflow with the following paragraphs:
At the same time, x86 defines quite a strict memory model, which bans most possible reorderings, roughly summarized as follows:
Stores have a single global order of visibility, observed consistently by all CPUs, subject to one loosening of this rule below. Local load operations are never reordered with respect to other local load operations.
Local store operations are never reordered with respect to other local store operations (i.e., a store that appears earlier in the instruction stream always appears earlier in the global order).
Local load operations may be reordered with respect to earlier local store operations, such that the load appears to execute earlier wrt the global store order than the local store, but the reverse (earlier load, older store) is not true.
To summarize, on x86 platforms, memory ordering is strong, and only store Load is out of order.
See you eight-part essay old immortal people back is really hard, this article provides a point can directly prove the means of these problems.
Perfbook uses a tool called Litmus to describe memory-barrier concepts, which is now integrated into HerdTools. Once you install HerdTools, you already have Litmus. We can test all of the above read-write reordering/out-of-order situations.
Read and write out-of-order test
X86 RW { x=0; y=0; } P0 | P1 ; MOV EAX,[y] | MOV EAX,[x] ; MOV [x],$1 | MOV [y],$1 ; locations [x;y;] exists (0:EAX=1 /\ 1:EAX=1) %%%%%%%%%%%%%%%%%%%%%%%%% % Results for sb.litmus % %%%%%%%%%%%%%%%%%%%%%%%%% X86 OOO {x=0; y=0; } P0 | P1 ; MOV EAX,[y] | MOV EAX,[x] ; MOV [x],$1 | MOV [y],$1 ; locations [x; y;] exists (0:EAX=1 /\ 1:EAX=1) Generated assembler ##START _litmus_P0 movl -4(%rsi,%rcx,4), %eax movl $1, -4(%rbx,%rcx,4) ##START _litmus_P1 movl -4(%rbx,%rcx,4), %eax movl $1, -4(%rsi,%rcx,4) Test OOO Allowed Histogram (2 states) 500000:>0:EAX=1; 1:EAX=0; x=1; y=1; 500000:>0:EAX=0; 1:EAX=1; x=1; y=1; No Witnesses Positive: 0, Negative: 1000000 Condition exists (0:EAX=1 /\ 1:EAX=1) is NOT validated Hash=7cdd62e8647b817c1615cf8eb9d2117b Observation OOO Never 0 1000000 Time OOO 0.14Copy the code
Write and read out of order test
X86 RW { x=0; y=0; } P0 | P1 ; MOV EAX,[y] | MOV EAX,[x] ; MOV [x],$1 | MOV [y],$1 ; locations [x;y;] exists (0:EAX=1 /\ 1:EAX=1) %%%%%%%%%%%%%%%%%%%%%%%%%% % Results for sb2.litmus % %%%%%%%%%%%%%%%%%%%%%%%%%% X86 OOO {x=0; y=0; } P0 | P1 ; MOV [x],$1 | MOV [y],$1 ; MOV EAX,[y] | MOV EAX,[x] ; locations [x; y;] exists (0:EAX=0 /\ 1:EAX=0) Generated assembler ##START _litmus_P0 movl $1, -4(%rbx,%rcx,4) movl -4(%rsi,%rcx,4), %eax ##START _litmus_P1 movl $1, -4(%rsi,%rcx,4) movl -4(%rbx,%rcx,4), %eax Test OOO Allowed Histogram (4 states) 2 *>0:EAX=0; 1:EAX=0; x=1; y=1; 499998:>0:EAX=1; 1:EAX=0; x=1; y=1; 499999:>0:EAX=0; 1:EAX=1; x=1; y=1; 1 :>0:EAX=1; 1:EAX=1; x=1; y=1; Ok Witnesses Positive: 2, Negative: 999998 Condition exists (0:EAX=0 /\ 1:EAX=0) is validated Hash=2d53e83cd627ba17ab11c875525e078b Observation OOO Sometimes 2 999998 Time OOO 0.12Copy the code
Read and write out of order test
I didn’t think of a good way to do this, so I mixed reading and writing to test that either WW would rearrange, or RR would rearrange, either in P0, EAX = 2, EBX = 0.
X86 OOO { x=0; y=0; } P0 | P1 ; MOV EAX,[x] | MOV [y],$1 ; MOV EBX,[y] | MOV [x],$2 ; locations [x;y;] exists (0:EAX=2 /\ 0:EBX=0)Copy the code
%%%%%%%%%%%%%%%%%%%%%%%%%% % Results for sb3.litmus % %%%%%%%%%%%%%%%%%%%%%%%%%% X86 OOO {x=0; y=0; } P0 | P1 ; MOV EAX,[x] | MOV [y],$1 ; MOV EBX,[y] | MOV [x],$2 ; locations [x; y;] exists (0:EAX=2 /\ 0:EBX=0) Generated assembler ##START _litmus_P0 movl -4(%rbx,%rcx,4), %eax movl -4(%rdx,%rcx,4), %r11d ##START _litmus_P1 movl $1, -4(%rdi,%rax,4) movl $2, -4(%rcx,%rax,4) Test OOO Allowed Histogram (3 states) 500000:>0:EAX=0; 0:EBX=0; x=2; y=1; 1 :>0:EAX=0; 0:EBX=1; x=2; y=1; 499999:>0:EAX=2; 0:EBX=1; x=2; y=1; No Witnesses Positive: 0, Negative: 1000000 Condition exists (0:EAX=2 /\ 0:EBX=0) is NOT validated Hash=74f6930f2a61d6cfec9fb5ea3132555e Observation OOO Never 0 1000000 Time OOO 0.11Copy the code