Skip to the content.

memory model litmus 测试

由内核模块 m/concurrent/memory_model.cm/concurrent/mm_ll.c 转换而来的用户态测试, 并补充了经典的 SB / MP / LB litmus 测试。使用 pthread + C11 stdatomic, Linux (gcc) 和 macOS / Asahi Linux (clang / gcc) 都可以直接编译。

构建和运行

// 参考: https://github.com/smcdef/memory-reordering

make            # 每个测试生成 xx-nofence.out 和 xx-fence.out 两个版本
./run-all.sh    # 每个测试跑 5 秒, 依次输出结果
./sb-nofence.out 10   # 也可以单独跑, 参数是秒数, 默认 10

测试变量一律是 volatile + compiler_barrier(), 禁止编译器重排, 因此观察到的都是 CPU 层面的乱序。 另外测试变量按 256B 对齐放到不同 cache line 上: 若共享一条 cache line, 两个 store 会随同一个 line 一起可见, mp / lb 几乎不可能触发。

测试列表

测试 litmus 检测的乱序结果 x86 (TSO) ARM
sb x=1; r1=yy=1; r2=x r1=0 且 r2=0 允许 允许
mp x=i; y=i 递增 ∥ r1=y; r2=x r1 > r2 禁止 允许
lb r1=x; y=1r2=y; x=1 r1=1 且 r2=1 禁止 允许
ll x=1; y=1r1=x; r2=y r1=1 且 r2=0 (假象, 见下) 不适用 不适用
wr x=1; y=1; y=0; x=0 循环 看到 y=1 且 x=0 禁止 允许
ss a=t; b=td=b; c=a d > c 禁止 允许

sb / lb / ll 用 watcher 每轮重置变量并 rendezvous 两个 actor (等价于内核版本里的 sem_x / sem_y / sem_end 信号量), mp / wr / ss 自由跑 (mp 用单调递增避免重置, wr / ss 和内核版本一致)。

实测结果

x86_64 (本机, Intel/AMD)

[sb-nofence] arch=x86: reorder(r1=0,r2=0) detected 4185618 / 18320364 iterations
[sb-fence]   arch=x86: reorder(r1=0,r2=0) detected 0 / 18426997 iterations
[mp-nofence] arch=x86: reorder(flag>data) detected 0 / 97452152 checks
[mp-fence]   arch=x86: reorder(flag>data) detected 0 / 170042961 checks
[lb-nofence] arch=x86: reorder(r1=1,r2=1) detected 0 / 15262854 iterations
[lb-fence]   arch=x86: reorder(r1=1,r2=1) detected 0 / 17369335 iterations
[ll-nofence] arch=x86: racy-timing(r1=1,r2=0) detected 124676 / 19134872 iterations (NOT a reorder proof)
[ll-fence]   arch=x86: racy-timing(r1=1,r2=0) detected 702165 / 17651800 iterations (NOT a reorder proof)
[wr-nofence] arch=x86: hits(y=1,x=0) 0 / 100433190 checks (fence 版本不归零说明是时间窗口假象)
[wr-fence]   arch=x86: hits(y=1,x=0) 8515 / 272122218 checks (fence 版本不归零说明是时间窗口假象)
[ss-nofence] arch=x86: reorder(d>c) detected 0 / 113936849 checks
[ss-fence]   arch=x86: reorder(d>c) detected 0 / 117962080 checks

aarch64 (Asahi Linux @ Apple Silicon, 100.113.183.51)

[sb-nofence] arch=arm: reorder(r1=0,r2=0) detected 95 / 29092460 iterations
[sb-fence]   arch=arm: reorder(r1=0,r2=0) detected 0 / 24077549 iterations
[mp-nofence] arch=arm: reorder(flag>data) detected 136589057 / 342861784 checks
[mp-fence]   arch=arm: reorder(flag>data) detected 0 / 183557732 checks
[lb-nofence] arch=arm: reorder(r1=1,r2=1) detected 0 / 33399335 iterations
[lb-fence]   arch=arm: reorder(r1=1,r2=1) detected 0 / 24703486 iterations
[ll-nofence] arch=arm: racy-timing(r1=1,r2=0) detected 4 / 33475849 iterations (NOT a reorder proof)
[ll-fence]   arch=arm: racy-timing(r1=1,r2=0) detected 174 / 26362565 iterations (NOT a reorder proof)
[wr-nofence] arch=arm: hits(y=1,x=0) 285199 / 3117154268 checks (fence 版本不归零说明是时间窗口假象)
[wr-fence]   arch=arm: hits(y=1,x=0) 2 / 3429056110 checks (fence 版本不归零说明是时间窗口假象)
[ss-nofence] arch=arm: reorder(d>c) detected 23585059 / 1462506076 checks
[ss-fence]   arch=arm: reorder(d>c) detected 0 / 193916441 checks

结果解读

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。