当前位置: 首页 > news >正文

volatile的进一步深入理解

一、relaxed 是什么意思?

在这里,relaxed 指的是内存访问的顺序不会被强制保证,也就是说:

编译器和 CPU 都可以对这次访问进行重排序优化


举个例子:
// 假设这是 SoC 的寄存器地址
#define DP_CTL    ((volatile uint32_t*)0xF9008000)
#define DP_START  ((volatile uint32_t*)0xF9008004)*DP_CTL = 0x1;
*DP_START = 0x1;

你想让它“先 enable,后 start”,但如果底层访问是 relaxed 的(比如 writel_relaxed()),那 CPU 可能这么执行:

  • 实际指令顺序:start → enable

这在硬件交互中是灾难性的,因为寄存器顺序不对,设备可能根本不启动。


所以“relaxed”访问:

  • 没有内存屏障(barrier)

  • 不能保证访问顺序

  • 适合“没有依赖关系”的访问,比如配置缓存

  • 不适合用于需要顺序写入的硬件寄存器

在 Linux 内核中:

writel(val, reg);          // 带 barrier(强顺序)
writel_relaxed(val, reg);  // 不带 barrier(弱顺序)


二、dead store elimination 是什么?

它是编译器的一种优化策略:

编译器会删除写入但从未读取的变量,因为它“看起来没用”。


举例:

int a = 42;
a = 43;

编译器会优化掉 a = 42,因为后面立马又改成了 43,前一次写入是“死掉的写入”。


问题来了:

如果这个变量是个 映射的寄存器地址,或会被其他线程读取,那这次“看起来没用”的写入其实是有意义的!

加上 volatile 后,编译器就不会删了


三、为什么volatile ≠ 原子性,但又说它能用于多线程共享变量?


volatile 能用于多线程共享变量吗?

是的,可以用于某些简单的多线程同步场景,比如状态标志、轮询退出等:

volatile bool stop = false;void worker_thread() {while (!stop) {// doing work}
}

主线程设置 stop = true;,worker 线程能马上看到。

但是,它不能保证原子性

举个例子:
volatile int counter = 0;thread 1: counter++;
thread 2: counter++;

每个 counter++ 实际是三步:

load → increment → store

多个线程可能交叉执行,造成 丢失更新(lost update)的问题!

所以:

volatile 适合用在 “单向通知” 的变量(比如标志位)
不适合用在 “读改写” 的变量(比如计数器、队列头尾)


正确方式:使用 atomic 或加锁

C++11 起提供了 std::atomic<T>,它:

  • 保证线程间的可见性(类似 volatile

  • 还提供原子性(atomicity)

  • 可选 memory ordering 模型(acquire/release/relaxed)


总结对比表:

特性volatilestd::atomic / 加锁
防编译器优化✅ 是✅ 是
防 CPU 重排序❌ 否✅ 可选(acquire 等)
保证原子性❌ 否✅ 是
多线程下安全⚠️ 有条件✅ 是
驱动开发适用✅ 非常适合❌ 不适合

小结一句话:

  • volatile 保证“每次访问都去读/写内存”,防止编译器优化,但不保证原子性或顺序性

  • relaxed 意味着“CPU 和编译器都可以优化访问顺序”,适合无依赖场景

  • 需要 顺序访问或多线程安全 时,必须加上 memory barrier 或 std::atomic

相关文章:

  • 如何导出pip下载的paho-mqtt包
  • 对比说明Navicat for MySQL和DBeaver的数据同步功能
  • Qt QTimer 详解与使用指南
  • VueRouter笔记
  • LeetCode 2364.统计坏数对的数目:反向统计
  • 深度学习3.2 线性回归的从零开始实现
  • (8)VTK C++开发示例 --- 交互式3D部件
  • VTK9 编译
  • Android 12.0 framework实现对系统语言切换的功能实现
  • Dubbo Filter如何实现Bean注入与配置文件读取?
  • 花园灌溉问题
  • 若依框架修改左侧菜单栏默认选中颜色
  • ChatUI vs Ant Design X 技术选型对比
  • win10系统完美配置mamba-ssm全整合方案
  • RAG-概述
  • `get_peft_model` 是 `peft` 库什么方法
  • 基于亚博K210开发板——内存卡读写文件
  • 如何删除 Launchpad 中 Chrome 的图标
  • java输出、输入语句
  • 【SAP ME 43】RESRCE表操作导致HANA中表锁定解决方案
  • 大家聊中国式现代化|权衡:在推进中国式现代化中当好龙头
  • 体坛联播|利兹联、伯恩利重返英超,北京淘汰北控队晋级四强
  • 张文宏:加强基层医疗体系建设,提升传染病早期监测和预警能力
  • 对话地铁读书人|财务管理孟先生:老婆让我看《三体》
  • 美国多地举行抗议活动,特朗普经济政策支持率创新低
  • AI时代教育如何变革?上海首批 “标准化家长学校”出炉