| 项目 | 值 |
|---|---|
| 替换算法 | FIFO、LRU、LFU、随机 |
| 写回法 | 只修改 Cache,换出时写回主存 |
| 全写法 | 同时写 Cache 和主存 |
当 Cache 满或发生冲突时,需要替换算法决定替换哪一行。当 CPU 写 Cache 时,需要写策略决定如何保持 Cache 与主存的一致性。
常见替换算法包括 LRU、FIFO、LFU 与随机替换,下面逐一说明。
替换最久没有被访问的行。
计数器法:每行维护一个计数器;命中时该行清 0、其余 +1;替换时选计数器最大的行。
栈算法:维护访问栈,命中时该行移到栈顶,替换时选栈底(最久未访问)。
访问序列:A B C A D B E
访问 A → 组0=[A,空] 未命中
访问 B → 组0=[A,B] 未命中
访问 C → 组0=[C,B] 替换 A(LRU)未命中
访问 A → 组0=[C,A] 替换 B 未命中
访问 D → 组0=[D,A] 替换 C 未命中
访问 B → 组0=[D,B] 替换 A 未命中
访问 E → 组0=[E,B] 替换 D 未命中
替换最早进入 Cache的行。每行记录进入时间或维护队列,新装入行排队尾,替换时选队首。
替换访问次数最少的行。每行维护访问计数器,访问 +1,替换时选最小者。需要较大计数器,历史数据可能过时,实际较少使用。
随机选一行替换。实现最简单、命中率不稳定,用于某些 TLB。
| 算法 | 命中率 | 实现复杂度 | Belady 异常 |
|---|---|---|---|
| LRU | 高 | 较复杂 | 无 |
| FIFO | 中 | 简单 | 有 |
| LFU | 高 | 复杂 | 无 |
| Random | 低 | 最简单 | 无 |
| OPT | 最高 | 不可实现 | 无 |
写直达(Write Through):同时写 Cache 和主存,二者始终一致;每次写都访存、速度慢,写缓冲(Write Buffer)可缓解。
写回(Write Back)⭐:只写 Cache,设脏位=1;该行被替换且脏位=1 时才写回主存。写速度快但可能不一致,现代 Cache 常用。
| 特性 | 写直达 | 写回 |
|---|---|---|
| 写速度 | 慢 | 快 |
| 数据一致性 | 好 | 差 |
| 主存写入次数 | 多 | 少 |
| 硬件复杂度 | 低 | 高(脏位) |
| 典型应用 | 早期系统 | 现代 Cache |
多核 CPU 每个核有私有 L1/L2 Cache、共享 L3,需保证同一数据在各 Cache 中的一致性。解决方案:MESI 协议(Modified/Exclusive/Shared/Invalid)、MOESI、监听协议(Snooping)、目录协议(Directory-based)。
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。