贝利信息

c++的std::atomic在ARM和x86架构下有何不同? (内存模型与硬件)

日期:2026-01-22 00:00 / 作者:穿越時空
ARM与x86的std::atomic内存序表现不一致,根源在于ARM采用弱内存模型而x86采用强内存模型,导致相同代码在两平台上的语义、开销及指令生成均不同。

std::atomic 的内存序在 ARM 和 x86 上表现不一致,根源是硬件内存模型差异

ARM 使用弱内存模型(Weak Mem

ory Model),x86 使用强内存模型(Strong Memory Model)。这意味着相同 C++ 代码在两种架构上,std::atomic 的默认行为和显式内存序的实际开销、语义约束都不同。不是“实现不同”,而是硬件不保证某些重排,编译器和运行时必须用额外指令补足。

x86 上 std::memory_order_relaxed 几乎无成本,ARM 上可能插入 dmb ish

x86 的 store-store、load-load、load-store 重排被硬件禁止,所以多数 std::atomic 操作(即使是 relaxed)无需内存屏障指令。ARM 则不然:即使 relaxed store,也可能被乱序到后续非原子访存之后,因此编译器常插入 dmb ish(inner shareable domain barrier)来满足 C++ 标准对“修改顺序一致性”的最低要求(尤其在多核间可见性上)。

std::memory_order_seq_cst 在 ARM 上代价显著更高

x86 天然提供顺序一致性(SC)语义,seq_cst load/store 通常不额外生成 barrier 指令(仅部分 store 可能加 mfence)。ARM 必须为每个 seq_cst 操作插入 full barrier(dmb ish),且 load-use 和 store-store 之间还需配对控制(例如 ldar/stlr 指令本身带 acquire/release 语义,但组合成 SC 需额外同步)。

// ARM64 Clang 15 -O2 生成的 seq_cst store
mov     x8, #1
stlr    w8, [x0]      // store-release
dmb     ish          // 强制全局顺序,x86 下这行通常不存在

ARM 的 ldar/stlr 指令不等于 x86 的 mov + 缓存一致性

x86 的 cache coherency 协议(MESIF/MOESI)天然保证所有核看到一致的写顺序,而 ARM 的 ldar(load-acquire)和 stlr(store-release)是**语义指令**,它们不保证全局顺序,只约束当前核的指令重排,并配合 dmb 实现跨核同步。误以为 “用了 stlr 就自动全序” 是常见误区。

实际写跨平台 std::atomic 代码时,最易被忽略的是:你以为的“安全重排”在 ARM 上根本不会发生,而你以为的“自然顺序”在 ARM 上必须靠显式内存序兜底。别依赖 x86 的宽容去验证正确性。