计算机体系结构 17:多级缓存与写入
多级缓存与写入
读 miss 只需要把缺失的 block 带到更近的位置。写访问多了一层约束:处理器已经修改了一份副本,下层存储何时看见这个修改?若替换时还有未写回的数据,旧 block 能否直接丢弃?这些问题决定了写策略、dirty bit 和多级缓存的平均访问时间。
本篇的核心问题是:write-through、write-back、write-allocate 和 no-write-allocate 分别改变哪条流量;脏块逐出怎样计入代价;AMAT 的条件概率公式何时能用?核心案例用 1 set × 2 way × 16B 的 write-back/write-allocate cache 追踪五次访问,并补一个 no-write-allocate 写 miss 的反例。证据等级为功能执行加手算。
实验目录为 examples/computer-architecture/cache/。本文附件包括 writeback_amat.json.txt、cache_model.py.txt 和 run_cases.py.txt。
四个写策略词不要混成一个选择
write-through 表示写命中时同时写 cache 和下层。write-back 表示先只改 cache line,把 dirty bit 置上,等这行被替换时再写回下层。
write-allocate 表示写 miss 时先把 block 装入 cache,再在 cache 中完成写。no-write-allocate 表示写 miss 不装入 cache,只把这次写转给下层。
因此常见组合有两类:write-through + no-write-allocate,适合避免一次写 miss 把很少再读的数据带进 cache;write-back + write-allocate,适合多次写同一 block 时合并下层流量。但这只是常见组合,不是逻辑必然。本模型显式覆盖了 write_back=True, write_allocate=False 的写 miss,证明即使不分配 line,这次 4B 写流量也不能消失。
写策略要拆成两个维度:命中时是否立刻下传,缺失时是否装入 cache。write-back 描述 dirty line 何时写回;write-allocate 描述 write miss 是否分配 cache line。二者独立,不能用一个词替代另一个。
五次访问的脏块轨迹
主案例固定操作序列:
1 | |
cache 参数为 1 set × 2 way × 16B,write-back + write-allocate,hit latency 为 1,fill latency 为 10。所有 block 都映射到同一个 set。逐次结果如下:
| 次序 | 操作 | block | 结果 | cache 内变化 | 下层流量 |
|---|---|---|---|---|---|
| 1 | read 0 | 0 | miss | 装入 block 0,clean | fill 16B |
| 2 | write 0 | 0 | hit | block 0 置 dirty | 0B |
| 3 | write 16 | 1 | miss | 装入 block 1,dirty | fill 16B |
| 4 | read 32 | 2 | miss | 淘汰 dirty block 0,装入 block 2 | fill 16B + writeback 16B |
| 5 | read 0 | 0 | miss | 淘汰 dirty block 1,装入 block 0 | fill 16B + writeback 16B |
模型输出为 fill_bytes=64、writeback_bytes=32、writebacks=2。注意第 2 次写命中没有立刻增加下层写流量,代价推迟到第 4 次逐出。write-back 不是减少语义上的写入次数,而是把多次写合并成更少的下层 block 写回。
第 5 次重新读取地址 0 时 miss,是容量缺失而不是冲突缺失。这个 cache 只有两行,访问过且仍可能需要的 block 有 0、1、2。即使改成同容量全相联,也只有两行。
no-write-allocate 的最小反例
另一个反例使用单独 cache:1 set × 1 way × 16B,write_back=True, write_allocate=False。第一次访问就是 write 0。
模型事件为:fill_bytes=0,lower_write_bytes=4。这说明 no-write-allocate 没有装入 16B block,但 4B store 仍要向下层发出。否则写操作就在模型里凭空消失。
这个反例的作用是防止把“write-back”误理解成“所有写都等到未来替换”。write-back 描述 cache line 已经存在且被写脏后的处理;no-write-allocate 的写 miss 没有 line 可脏化,只能把本次写交给下层。
AMAT 是概率树,不是所有延迟的总公式
单级 AMAT 写作:
1 | |
两级缓存常写成递归形式:
1 | |
本文手算参数为 L1_hit=1、L1_miss_rate=0.25、L2_hit=8、L2_local_miss_rate=0.5、memory_penalty=80。代入得:
1 | |
这里的 L2_local_miss_rate 是“已经 miss L1 的访问里,又 miss L2 的比例”,不是全部访存的 L2 miss 比例。CS61C 的 AMAT 教材也按这个条件概率口径展开两级公式。
AMAT 适用于平均、独立、无重叠的访问延迟估算。它不描述 MSHR 重叠、乱序隐藏、预取提前、写缓冲排队或 DRAM bank 并行。若后续模型引入 MLP,同一个 miss penalty 不再简单逐项相加。
AMAT 是一棵概率树。每一层的 miss rate 必须说明分母,公式才能读。L2 local miss rate 的分母是已经到达 L2 的访问;若使用全局 miss rate,公式需要相应改写。
脏块逐出与平均时间的边界
本案例把 dirty eviction 的额外时间粗略写成一个 fill latency。这样做只用于展示“写回也占用下层带宽和时间”,不代表真实内存控制器的读写切换、写缓冲吸收或总线仲裁。
若写缓冲足够深,处理器看到的等待可能小于实际写回完成时间;若写缓冲满了,后续 miss 可能被迫等待。若 cache 层级 inclusive 或需要维护一致性,dirty line 的位置还会影响后续协议消息。本文不覆盖这些机制。
验收时不应只看最后 AMAT=13。更重要的是能指出:第 4、5 次访问为什么各有一次 dirty eviction;为什么 no-write-allocate 仍有 4B 下层写;为什么 L2 miss rate 的分母是 L1 misses。
复跑与验收
执行:
1 | |
本篇关注 outputs/writeback_amat.json。应核对主案例 fills=4、fill_bytes=64、writebacks=2、writeback_bytes=32;AMAT 为 13.0;no-write-allocate 反例中 fill_bytes=0 且 lower_write_bytes=4。
这些记录证明的是教学模型中的写策略和计数口径。没有测量真实 cache 的 writeback 事件,也没有证明某款处理器采用同一写策略。
两道练习
练习一: 若第 3 次 write 16 改为 write-through + write-allocate,写 miss 装入 block 后是否还需要向下层写 4B?
解答:需要。write-allocate 决定装入 block;write-through 决定写命中或装入后的写同时下传。因此这次既有 16B fill,也有 4B lower write。具体系统可能合并或重排总线事务,但语义流量不能写成 0。
练习二: 某资料给出 L1 miss rate 10%,L2 global miss rate 2%,L1 hit 1 cycle,L2 hit 8 cycles,memory penalty 100 cycles。若公式需要 L2 local miss rate,应填多少?AMAT 是多少?
解答:L2 global miss rate 是全部访问中 miss L2 的比例,L1 miss rate 是进入 L2 的比例。local miss rate 为 0.02 / 0.10 = 0.2。AMAT 为 1 + 0.10 × (8 + 0.2 × 100) = 3.8 cycles。
参考资料
- CS61C:Average Memory Access Time。2026-09-22 核查;支持 AMAT 基本公式和两级 local miss rate 口径。
- CS61C:Fully Associative Cache。2026-09-22 核查;支持 write-through、write-back、dirty bit 等教学表述。
- gem5:Classic Caches。2026-09-22 核查;支持 classic cache 默认含 MSHR/write buffer、可配置替换和索引策略。
- 本系列 cache 教学模型。本文实际附件来自本地工作区当前输出,不声称 GitHub 链接已经包含本轮未提交文件。





