计算机组成原理 | Cache替换算法

计算机组成原理 | Cache 满了怎么办?四大替换算法深度解析

摘要/导语:

嗨!上两期我们搞定了 Cache 的映射方式,解决了"数据怎么放进 Cache"的问题。但后台有同学问:"Cache 空间那么小,如果放满了,新数据来了怎么办?"

没错,这就是我们今天要讲的硬核内容------Cache 替换算法。当 Cache 满员时,谁走谁留?是随机踢人,还是按资排辈?不同的策略直接决定了你的程序跑得是快如闪电还是卡顿如牛。

今天这篇推文将带你彻底拆解 RAND、FIFO、LRU、LFU 这四大算法。文末附带了经典的 LRU 栈模拟法和 408 真题解析,帮你搞定期末和考研!


🚀 正文内容

🤔 第一部分:为什么要替换?

Cache 之所以快,是因为它小且贵。既然小,就注定装不下所有的主存数据。

当 CPU 想要访问的数据不在 Cache 中(发生 Miss ),且此时 Cache 已经满了,控制器就必须做出一个艰难的决定:把哪一块旧数据踢出去(替换),给新数据腾位置?

这个决定的过程,就是替换算法 。我们的目标只有一个:让命中率尽可能高!


⚔️ 第二部分:四大算法大乱斗

我们来看看教科书里最经典的四种算法,看看它们都是怎么"做决定"的。

1. 随机算法 (RAND)
  • 核心逻辑:主打一个"随缘"。当需要替换时,随机挑选一块 Cache 行进行替换。
  • 评价:过于 Freestyle。虽然实现起来极其简单(甚至不需要硬件计数器),但它完全不看数据的脸色,效果通常很差。
  • 现状:基本只存在于理论教学中,实际系统很少用。
2. 先进先出算法 (FIFO)
  • 核心逻辑 :排队论。优先替换最早被调入 Cache 的那块数据。就像食堂排队打饭,先来的人先走。
  • 实现细节 :需要一个计数器或者队列来记录进入的顺序。这里有个考点:如果 Cache 块的总数为 2n2^n2n,那么计数器只需要 nnn 位二进制数就够了(比如 8 个块只需要 3 位)。
  • 致命弱点不遵循局部性原理!
    • 场景:有些数据虽然是很久以前进来的(比如操作系统的内核代码),但它可能一直被频繁使用。FIFO 会无情地把它踢掉,导致下次还要重新调入,反而降低了效率。
3. 近期最少使用算法 (LRU) ------ 重点中的重点!
  • 核心逻辑 :基于"时间局部性"。既然你最近没用过这块数据,那你未来大概率也不会用它。所以,淘汰那个"最久没有被访问过"的块
  • 为什么它最强?
    • 它完美契合了程序的运行规律:刚刚被访问过的指令或数据,很可能马上又要被访问。
    • 实际运行效果优秀,Cache 命中率高,是目前高性能计算机中最常用的算法之一。
  • 硬件代价:为了实现它,每个 Cache 行都需要设置一个"计数器"或寄存器,用来记录该块多久没被访问了。这会带来一定的硬件开销。
4. 最不经常使用算法 (LFU)
  • 核心逻辑:看"人气"。将被访问次数最少的主存块替换。
  • 实现:每个 Cache 行设置一个计数器,记录被访问过多少次。每次访问,计数器 +1;替换时,找计数器最小的。
  • 致命弱点"曾经辉煌不代表未来"
    • 场景:一个数据在程序刚开始时被疯狂访问(计数器很高),但后面再也不用了。LFU 会因为它的历史成绩好而一直保留它,占着茅坑不拉屎,导致实际运行效果不如 LRU。

💡 第三部分:考试实战 ------ LRU 到底怎么算?

这是期末考试和 408 考研最爱出的题型:给定一个 Cache 容量和一个访问序列,问你命中了几次?或者最后 Cache 里剩什么?

解题神器:栈模拟法(Stack Simulation)

想象你手里有一叠盘子(Cache 块),每次拿到一个新盘子(访问数据):

  1. 如果盘子在栈里(命中) :把它抽出来,放到栈顶(表示它是最新的)。
  2. 如果盘子不在栈里(未命中)
    • 如果栈没满:直接把新盘子放栈顶。
    • 如果栈满了:把栈底那个盘子扔掉(它是最久没用的),然后把新盘子放栈顶。

【经典例题】

假设 Cache 能放 3 个块,访问序列为:1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5。请计算命中率。

【解题步骤】

  • 访问 1:栈 1 (未命中)
  • 访问 2:栈 2, 1 (未命中)
  • 访问 3:栈 3, 2, 1 (未命中,栈满)
  • 访问 4:4 不在栈里,踢掉栈底的 1。栈 4, 3, 2 (未命中)
  • 访问 1:1 不在栈里,踢掉栈底的 2。栈 1, 4, 3 (未命中)
  • 访问 2:2 不在栈里,踢掉栈底的 3。栈 2, 1, 4 (未命中)
  • ...以此类推

(注:做题时一定要画表格,一行一行写,千万别心算,很容易出错!)


🎓 第四部分:408 真题演练

(2015年 408 统考题)

某计算机的 Cache 共有 16 块,采用 2 路组相联映射方式(即每组 2 块)。每个主存块大小为 32B,按字节编址。主存地址为 129 号单元开始的一个主存块,其首地址是多少?若采用 LRU 替换算法,...(题目省略部分,重点考察映射与替换结合)

解析思路:

  1. 先算块号:129 / 32 = 4 ... 1。说明 129 号单元位于第 4 号主存块(从 0 开始数)。
  2. 再算组号:Cache 共 16 块,2 路组相联,说明有 16/2 = 8 个组。
  3. 映射:主存块号 4 映射到 Cache 的组号 = 4 % 8 = 4。
  4. 替换判断:如果此时第 4 组的两个位置都满了,就要看谁是 LRU(最久没用),把它换掉。

📝 总结时刻
算法 核心思想 优点 缺点 推荐指数
RAND 随机踢人 简单 效果差
FIFO 先来后到 实现简单 违背局部性 ⭐⭐
LRU 淘汰最久未用 命中率高,符合局部性 硬件复杂 ⭐⭐⭐⭐⭐
LFU 淘汰用得最少的 考虑历史热度 无法反映近期趋势 ⭐⭐⭐

思考题:

如果 Cache 只有 1 路(直接映射),还需要替换算法吗?为什么?

相关推荐
kgduu1 小时前
cosmos学习笔记
笔记·学习
AI_零食2 小时前
鸿蒙PC Electron跨平台应用开发:辗转相除法计算器实现详解
前端·学习·华为·electron·开源·鸿蒙·鸿蒙系统
weixin_428005302 小时前
C#调用 AI学习从0开始-第2阶段(Function Calling+工具调用智能体)-第9天实战
人工智能·学习·ai·c#·functioncalling
SNSZR12 小时前
2026 AI实操五大学习思路:破解碎片化自学无法落地商用项目的核心痛点
人工智能·学习
落地加湿器2 小时前
从Hermes cli的源代码中学习skill
人工智能·python·学习·智能体·源码解读
MartinYeung52 小时前
[论文学习]人工智慧启用系统的隐私增强技术:威胁分析、PETs 应用框架
学习·威胁分析
浩风祭月2 小时前
Coding-Interview-University 学习路径实测与效能评估
学习
惜年_night2 小时前
Go语言学习-04结构体/自定义类型/接口
学习
3DVisionary2 小时前
高温下钢管如何测应变?数字散斑DIC高温压缩测试方案
数码相机·学习·全场应变测量·实验力学·数字散斑dic·高温材料测试·钢管轴向压缩