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

多核处理器系统中内存一致性问题举例

单核处理器系统中 store buffer 的可见性 这里说了 单核情况下 一个示例程序 因为 两点的存在导致的 内存一致性问题

  1. store 指令 从 store buffer “出队” 的顺序 不能保证先入先出
  2. Store Buffer Forwarding 有限制条件,在部分情况下不能Forwarding
  • 即 在 X86 下 ,单核不存在内存一致性问题 ,但在ARM/riscv 下,单核存在内存一致性问题
  • 那么 我们将其 扩展为多核 ,如果 单核 存在内存一致性问题, 那么 多核照样存在内存一致性问题

不过我们 提出一个新的 场景 , 即多核场景下的 因为一个新的原因导致的 内存一致性问题,原因为

  1. 不保证写的顺序可见性
多核场景下,有cache,有store buffer  
一开始内存中 ready 为 0 , data 为 0// 用户函数     运行在 core 0 
data  = 123;  // S1
ready = 1  ; // S2// 用户函数     运行在 core 1 
if (ready == 1) {assert(data == 123);
}此时我们假设 store 指令 按照 程序编码顺序 "出队", // 虽然在 弱一致性模型中,这个不能保证
那么 assert 会失败吗?
虽然 在core 0 而言指令 S1 和 S2 按照程序顺序提交,在core1看来其顺序未必相同
例如对 ready 的写可能会较快的传播到处理器1(可能因为缓存命中)而对 data 的写 可能会比较慢地传播到处理器1(可能因为缓存缺失)

🧠 反方观点1 : 我认为 不管快慢, 都是会读到的, 只会导致 流水线 stall 而已 , 所以 assert 不会失败

你说的“流水线 stall,等到读到再继续”,这种理解适用于单核或强一致模型(如 x86),但在 多核弱一致模型中,读取操作不会 stall 去等待一致性,而是读取当前可见的值

✅ 在弱一致模型中(如 ARM/RISC-V):

  • Core 0data=123 写入其 store buffer → cache
  • 紧接着 ready=1 也写入其 cache;

这两次写入虽然在 Core 0 看是顺序的,但:

  • Core 1 在访问 ready 时,如果它的 cache 失效,会向系统请求 ready 的缓存行,可能很快被刷新到了内存并响应;
  • data 对应的缓存行可能还没刷新或系统没有通知 Core 1 其缓存无效(Invalidate Miss);
  • 所以 Core 1 在这时看到了 ready==1,却还没看到 data==123

这就出现了你说的那个令人惊讶的情况:

if (ready == 1) {assert(data == 123); // 这里失败
}

✅ 为什么会这样?根本原因是内存模型

架构是否允许这种乱序可见性(S2可见但S1不可见)
x86❌ 不允许:Store 被强制顺序可见(TSO)
ARM✅ 允许:Weak Ordering
RISC-V✅ 允许:Weak Ordering

所以在 ARM/RISC-V 上,除非你加上 memory barrier(内存屏障),否则确实可能出现:

  • data 还没传播出去,
  • ready 已经传播到其他核,
  • 导致其他核看到不一致状态。

✅ 为什么不“stall”等待写都可见呢?

因为:

  • 读取操作不是同步操作,不会等待写入同步完毕。
  • 多核系统设计目标是并发性和性能,不会为了“等待另一个核心的数据刷新”而主动阻塞读取。
  • 如果需要保证顺序,需要**人为添加屏障(memory barrier)**或用同步机制(如锁、原子操作)。

✅ 如果你希望 assert 不失败,该怎么做?

在 Core 0 上:

data = 123;
dmb();         // 数据内存屏障,确保 data 的写对其他核心可见
ready = 1;

或用 C11 原子写:

atomic_store_explicit(&data, 123, memory_order_relaxed);
atomic_store_explicit(&ready, 1, memory_order_release);

在 Core 1 上:

if (atomic_load_explicit(&ready, memory_order_acquire)) {assert(atomic_load_explicit(&data, memory_order_relaxed) == 123);
}

这种用法利用了 release-acquire 同步语义,能确保 Core1 在看到 ready==1 后,也看到之前的 data 写。


✅ 总结

问题是否成立说明
多核系统会 stall 直到看到一致的数据不会,读取会看到“当前可见的值”,不等于等待一致
store buffer 是 FIFO,所以写顺序一致✅/❌顺序进入 store buffer,但何时对其他核心可见不一定顺序
传播快慢是否只是影响延迟在弱一致模型下,传播差异导致可见顺序乱序,进而出现 assert 失败
assert(data == 123) 会失败吗✅ 可能在 ARM/RISCV 等架构上,确实可能,如果没有内存屏障
http://www.dtcms.com/a/240762.html

相关文章:

  • PydanticAI快速入门示例
  • React事件处理:如何给按钮绑定onClick点击事件?
  • 运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.
  • L1和L2核心区别 !!--part 2
  • AI书签管理工具开发全记录(十八):书签导入导出
  • 【大模型:知识库管理】--开源工具Ragflow构建知识库
  • 【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
  • 归并排序算法及其在算法中的应用
  • 运动控制--小车的启动和停止算法
  • 1-6 Linux-虚拟机快照(2025.6.9学习篇)
  • WSL从C盘迁移到D盘
  • 客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
  • 多元隐函数 偏导公式法 (显示变化 + 隐式变化)
  • 如何快速进行光伏发电量计算?
  • 网络爬虫解析技术与实战代码详解
  • Python应用输入输出函数
  • 【samba】umount:**** target is busy. ubuntu24.04 卸载挂载点
  • Linux离线(zip方式)安装docker
  • T型槽试验平台及其应用
  • 循环语句之while
  • java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
  • 多模态大语言模型arxiv论文略读(113)
  • web vue 项目 Docker化部署
  • QT3D学习笔记——圆台、圆锥
  • 本地化部署 Dify 打造专属 AI 助手并嵌入网站
  • 门静脉高压——表现
  • 2021-03-15 iview一些问题
  • 在 Spring Boot 项目里,MYSQL中json类型字段使用
  • 开发认知提升
  • Kubernetes ClusterIP 端口深度解析:虚拟服务与流量转发机制