内存序是 Rust 并发里最难直觉的部分。这篇先证明原子操作与原子逻辑不是一回事,再测不同 Ordering 的成本,最后在 aarch64 上真的跑出 Relaxed 的异常结果,让 Release / Acquire 的作用变得可见。
编译:成功
运行(退出码 0):
fetch_add: 期望 4000000,实际 4000000
load + store: 期望 4000000,实际 1005154(丢失了更新) 编译:成功
运行(退出码 0):
Relaxed 单线程 1.93 ns/次 4 线程争用 18.93 ns/次(每次操作的平均墙钟时间)
AcqRel 单线程 3.74 ns/次 4 线程争用 30.02 ns/次(每次操作的平均墙钟时间)
SeqCst 单线程 3.74 ns/次 4 线程争用 29.11 ns/次(每次操作的平均墙钟时间)耗时是本机微基准,各次测量之间有噪声。
编译:成功 第 1 次运行(每次 100 万轮):Relaxed/Relaxed 异常 2 次;Release/Acquire 异常 0 次 第 2 次运行(每次 100 万轮):Relaxed/Relaxed 异常 24 次;Release/Acquire 异常 0 次 第 3 次运行(每次 100 万轮):Relaxed/Relaxed 异常 3 次;Release/Acquire 异常 0 次 第 4 次运行(每次 100 万轮):Relaxed/Relaxed 异常 672 次;Release/Acquire 异常 0 次
下一篇讲 CAS:Atomic CAS 操作。