缓存刷新、失效与清理指令
更新时间:2026-10-01。DMA、JIT/自修改代码场景,仅靠硬件 MESI 不够,需要按方向做缓存维护。
本文要回答的问题
- clean 和 invalidate 差在哪?
- DMA 与 CPU 共享内存时谁要刷缓存?
一、按数据流向
- 外设/DMA → 内存,CPU 读:若缓存可能持有旧行,先 invalidate(丢弃),让 CPU 重新从内存取。
- CPU 写 → 内存,DMA 读:先 clean/writeback,把脏数据落内存。
- 系统若有 IO 一致性(IOMMU/snoop)可免部分操作,但非所有平台都保证。
二、指令缓存与自修改代码
JIT 写入新代码后,要把 D-cache 写回并使对应 I-cache 行失效,再做流水线/推测同步(ISB),否则核可能执行旧指令。
三、常见坑
- 方向搞反(该 invalidate 却 clean)。
- JIT 后只 flush D-cache 不处理 I-cache。
- 维护范围过大浪费、或漏屏障。
小结
按数据流向选 invalidate/clean,自修改代码还要同步 I-cache 与流水线,操作范围和屏障要精确。下一篇 缓存预热与冷启动。
总结
硬件 MESI 管的是核与核之间,DMA 和自修改代码必须由软件按数据流向显式维护:外设写入内存后 CPU 读取前先 invalidate 丢弃可能的旧行,CPU 写完给 DMA 前先 clean/writeback 落盘,JIT 写入新代码后还要回写 D-cache、失效 I-cache 并用 ISB 同步流水线;维护范围过大浪费性能、漏掉屏障则读到旧数据。clean 和 invalidate 方向相反、用错场景就是最难查的陈旧数据 bug。