使用 Litmus 验证内存重排

存储 存储软件
perfbook 一书在讲 memory barrier 相关的概念时,都使用了一个叫 litmus 的工具,现在被集成在 herdtools[2] 中,安装好 herdtools 就已经有了 litmus,上面提到的所有读写重排/乱序的情况我们都可以进行测试。

[[405494]]

本文转载自微信公众号「码农桃花源」,作者曹春晖。转载本文请联系码农桃花源公众号。

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.

简单概括一下,就是在 x86 平台采用较强的内存序,只有 store load 会发生乱序。

看各位八股文老仙们背的实在辛苦,本文提供一点可以直接实操证明这些问题的手段。

perfbook 一书在讲 memory barrier 相关的概念时,都使用了一个叫 litmus 的工具,现在被集成在 herdtools[2] 中,安装好 herdtools 就已经有了 litmus,上面提到的所有读写重排/乱序的情况我们都可以进行测试。

读写乱序测试

  1. X86 RW 
  2. { x=0; y=0; } 
  3.  P0          | P1          ; 
  4.  MOV EAX,[y] | MOV EAX,[x] ; 
  5.  MOV [x],$1  | MOV [y],$1  ; 
  6. locations [x;y;] 
  7. exists (0:EAX=1 /\ 1:EAX=1) 
  1. %%%%%%%%%%%%%%%%%%%%%%%%% 
  2. % Results for sb.litmus % 
  3. %%%%%%%%%%%%%%%%%%%%%%%%% 
  4. X86 OOO 
  5.  
  6. {x=0; y=0;} 
  7.  
  8.  P0          | P1          ; 
  9.  MOV EAX,[y] | MOV EAX,[x] ; 
  10.  MOV [x],$1  | MOV [y],$1  ; 
  11.  
  12. locations [x; y;] 
  13. exists (0:EAX=1 /\ 1:EAX=1) 
  14. Generated assembler 
  15.  ##START _litmus_P0 
  16.  movl -4(%rsi,%rcx,4), %eax 
  17.  movl $1, -4(%rbx,%rcx,4) 
  18.  ##START _litmus_P1 
  19.  movl -4(%rbx,%rcx,4), %eax 
  20.  movl $1, -4(%rsi,%rcx,4) 
  21.  
  22. Test OOO Allowed 
  23. Histogram (2 states) 
  24. 500000:>0:EAX=1; 1:EAX=0; x=1; y=1; 
  25. 500000:>0:EAX=0; 1:EAX=1; x=1; y=1; 
  26. No 
  27.  
  28. Witnesses 
  29. Positive: 0, Negative: 1000000 
  30. Condition exists (0:EAX=1 /\ 1:EAX=1) is NOT validated 
  31. Hash=7cdd62e8647b817c1615cf8eb9d2117b 
  32. Observation OOO Never 0 1000000 
  33. Time OOO 0.14 

写读乱序测试

  1. X86 RW 
  2. { x=0; y=0; } 
  3.  P0          | P1          ; 
  4.  MOV EAX,[y] | MOV EAX,[x] ; 
  5.  MOV [x],$1  | MOV [y],$1  ; 
  6. locations [x;y;] 
  7. exists (0:EAX=1 /\ 1:EAX=1) 
  1. %%%%%%%%%%%%%%%%%%%%%%%%%% 
  2. % Results for sb2.litmus % 
  3. %%%%%%%%%%%%%%%%%%%%%%%%%% 
  4. X86 OOO 
  5.  
  6. {x=0; y=0;} 
  7.  
  8.  P0          | P1          ; 
  9.  MOV [x],$1  | MOV [y],$1  ; 
  10.  MOV EAX,[y] | MOV EAX,[x] ; 
  11.  
  12. locations [x; y;] 
  13. exists (0:EAX=0 /\ 1:EAX=0) 
  14. Generated assembler 
  15.  ##START _litmus_P0 
  16.  movl $1, -4(%rbx,%rcx,4) 
  17.  movl -4(%rsi,%rcx,4), %eax 
  18.  ##START _litmus_P1 
  19.  movl $1, -4(%rsi,%rcx,4) 
  20.  movl -4(%rbx,%rcx,4), %eax 
  21.  
  22. Test OOO Allowed 
  23. Histogram (4 states) 
  24. 2     *>0:EAX=0; 1:EAX=0; x=1; y=1; 
  25. 499998:>0:EAX=1; 1:EAX=0; x=1; y=1; 
  26. 499999:>0:EAX=0; 1:EAX=1; x=1; y=1; 
  27. 1     :>0:EAX=1; 1:EAX=1; x=1; y=1; 
  28. Ok 
  29.  
  30. Witnesses 
  31. Positive: 2, Negative: 999998 
  32. Condition exists (0:EAX=0 /\ 1:EAX=0) is validated 
  33. Hash=2d53e83cd627ba17ab11c875525e078b 
  34. Observation OOO Sometimes 2 999998 
  35. Time OOO 0.12 

读读和写写乱序测试

这里我没想到太好的办法,所以将读读和写写混在一起进行测试,无论是 WW 会发生重排,或是 RR 会发生重排,都可能会出现在 P0 中,EAX = 2,EBX = 0 的情况。

  1. X86 OOO 
  2. { x=0; y=0; } 
  3.  P0          | P1          ; 
  4.  MOV EAX,[x] | MOV [y],$1  ; 
  5.  MOV EBX,[y] | MOV [x],$2  ; 
  6. locations [x;y;] 
  7. exists (0:EAX=2 /\ 0:EBX=0) 
  1. %%%%%%%%%%%%%%%%%%%%%%%%%% 
  2. % Results for sb3.litmus % 
  3. %%%%%%%%%%%%%%%%%%%%%%%%%% 
  4. X86 OOO 
  5.  
  6. {x=0; y=0;} 
  7.  
  8.  P0          | P1         ; 
  9.  MOV EAX,[x] | MOV [y],$1 ; 
  10.  MOV EBX,[y] | MOV [x],$2 ; 
  11.  
  12. locations [x; y;] 
  13. exists (0:EAX=2 /\ 0:EBX=0) 
  14. Generated assembler 
  15.  ##START _litmus_P0 
  16.  movl -4(%rbx,%rcx,4), %eax 
  17.  movl -4(%rdx,%rcx,4), %r11d 
  18.  ##START _litmus_P1 
  19.  movl $1, -4(%rdi,%rax,4) 
  20.  movl $2, -4(%rcx,%rax,4) 
  21.  
  22. Test OOO Allowed 
  23. Histogram (3 states) 
  24. 500000:>0:EAX=0; 0:EBX=0; x=2; y=1; 
  25. 1     :>0:EAX=0; 0:EBX=1; x=2; y=1; 
  26. 499999:>0:EAX=2; 0:EBX=1; x=2; y=1; 
  27. No 
  28.  
  29. Witnesses 
  30. Positive: 0, Negative: 1000000 
  31. Condition exists (0:EAX=2 /\ 0:EBX=0) is NOT validated 
  32. Hash=74f6930f2a61d6cfec9fb5ea3132555e 
  33. Observation OOO Never 0 1000000 
  34. Time OOO 0.11 

[1]

这么: https://stackoverflow.com/questions/50307693/does-an-x86-cpu-reorder-instructions

[2]

herdtools: https://github.com/herd/herdtools7

 

责任编辑:武晓燕 来源: 码农桃花源
相关推荐

2020-11-08 14:32:01

JavaScript变量内存管理

2024-01-10 08:03:25

JMM重排序处理器

2010-11-30 15:31:38

SharePoint Kerberos

2010-02-26 09:18:24

Visual Stud

2010-06-02 11:06:15

Linux 内存监控

2010-09-25 12:38:40

JVM内存模型

2009-09-22 12:57:42

ibmdwWeb

2014-06-09 10:33:40

2023-09-19 08:00:00

Python开发

2009-08-03 17:31:26

.NET验证控件

2009-03-20 14:38:14

CAM介绍CAMXML结构验证

2010-11-08 10:07:23

SQL Server内

2018-11-14 19:30:57

前端Javascript性能优化

2014-07-03 09:39:34

Java内存分析mat工具

2019-09-17 14:31:37

磁盘排序IO

2019-06-29 14:34:27

磁盘IO排序

2021-10-29 11:27:52

链表数据结构算法

2013-08-27 14:23:18

浏览器重绘

2009-08-04 15:20:59

ASP.NET数据验证数据验证控件

2010-07-20 16:30:44

MySQL内存
点赞
收藏

51CTO技术栈公众号