0

0

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

穿越時空

穿越時空

发布时间:2026-01-22 18:06:35

|

227人浏览过

|

来源于php中文网

原创

ARM与x86的std::atomic内存序表现不一致,根源在于ARM采用弱内存模型而x86采用强内存模型,导致相同代码在两平台上的语义、开销及指令生成均不同。

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

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

ARM 使用弱内存模型(Weak Memory 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::atomic x{0}, y{0};,线程 A 执行 x.store(1, std::memory_order_relaxed); y.store(1, std::memory_order_relaxed);,线程 B 观察到 y==1 && x==0 在 x86 不可能,在 ARM 是可能的 —— 除非加 std::memory_order_release/acquire 或显式 barrier
  • Clang/GCC 在 ARM64 下对 relaxed store 常生成 str w0, [x1] + dmb ish;x86-64 下通常只有 mov dword ptr [rdi], esi

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 需额外同步)。

Remove.bg
Remove.bg

AI在线抠图软件,图片去除背景

下载
// ARM64 Clang 15 -O2 生成的 seq_cst store
mov     x8, #1
stlr    w8, [x0]      // store-release
dmb     ish          // 强制全局顺序,x86 下这行通常不存在
  • 频繁使用 seq_cst 会显著拖慢 ARM 多核性能,尤其在高争用计数器场景
  • 若逻辑只需 acquire-release 语义(如锁、状态标志),应显式用 memory_order_acquire/release,避免无谓升级为 seq_cst
  • 注意:GCC/Clang 对 seq_cst 的优化策略不同,ARM 下 GCC 更倾向插入 dmb,Clang 可能复用 ldar/stlr 的隐含语义,但跨操作的顺序仍需 barrier

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

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

立即学习C++免费学习笔记(深入)”;

  • stlr 保证该 store 不会重排到其后的任何访存之前,但不保证其他核立即看到 —— 还需 cache line 的 write-back 和 snoop 响应
  • ARMv8.3+ 引入 LDAPR(load-acquire, prefetch)等变种,但标准 std::atomic 实现不依赖这些扩展
  • 调试时若发现 ARM 上原子变量更新延迟可见,先检查是否混用了 non-atomic 访问(破坏了 compiler barrier),再确认是否漏了 acquire/release 匹配
实际写跨平台 std::atomic 代码时,最易被忽略的是:你以为的“安全重排”在 ARM 上根本不会发生,而你以为的“自然顺序”在 ARM 上必须靠显式内存序兜底。别依赖 x86 的宽容去验证正确性。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

482

2023.08.10

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

53

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

28

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

360

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

110

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

15

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

9

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号