计算机组成原理(15) 第二章 - Cache

Cache(高速缓冲存储器)是计算机体系中位于CPU 与主内存(RAM)之间的一种高速小容量存储部件,核心目的是解决 CPU 运算速度与主内存读写速度不匹配的 "速度鸿沟",从而提升整个系统的运行效率。其基本原理围绕 "局部性原理" 展开,并通过高效的映射、替换与写策略实现数据的快速存取。

一、核心前提:局部性原理

Cache 存在的物理基础是程序与数据访问的局部性------CPU 在一段时间内,对内存的访问往往集中在一个较小的 "热点区域",而非随机分散在整个内存空间。这种局部性分为两类:

  1. 时间局部性:如果一个数据 / 指令被 CPU 访问过,那么它在短期内很可能被再次访问(例如循环代码、频繁使用的变量)。
  2. 空间局部性:如果一个数据 / 指令被访问,那么它相邻地址的数据 / 指令也很可能被访问(例如数组、连续的代码段)。

Cache 正是利用这一特性,将 CPU 近期可能访问的 "热点数据 / 指令" 从速度较慢的主内存复制到速度极快的 Cache 中。当 CPU 再次访问时,优先从 Cache 读取,避免直接访问主内存,从而节省时间。

二、核心概念:Cache 的 "分层" 与 "命中 / 缺失"

1. Cache 的分层结构

为进一步优化速度与成本的平衡,现代 CPU 通常采用多级 Cache 架构(从 CPU 核心向外,速度递减、容量递增),常见结构为:

  • L1 Cache(一级缓存):紧挨着 CPU 核心,容量最小(通常每核心 32KB-128KB),速度最快(延迟仅 1-3 个 CPU 时钟周期),分为 "指令 Cache(L1I)" 和 "数据 Cache(L1D)",分别存储 CPU 待执行的指令和待处理的数据。
  • L2 Cache(二级缓存):容量中等(通常每核心 256KB-2MB),速度次之(延迟 5-10 个时钟周期),通常为单个 CPU 核心独享,存储 L1 Cache 无法容纳的 "次热点" 数据 / 指令。
  • L3 Cache(三级缓存):容量最大(通常 8MB-128MB),速度相对较慢(延迟 20-40 个时钟周期),多为多个 CPU 核心共享,服务于整个 CPU 的 "全局热点" 数据。

对比参考:主内存(RAM)的延迟通常为 100-200 个时钟周期,速度远低于Cache。

2. 命中与缺失

Cache 的核心性能指标围绕 "是否成功从 Cache 获取数据" 展开:

  • Cache 命中(Hit):CPU 请求的数据 / 指令已存在于 Cache 中,直接从 Cache 读取,速度极快。
  • Cache 缺失(Miss):CPU 请求的数据 / 指令不在 Cache 中,必须从主内存读取。此时需先将主内存中的 "热点块" 加载到 Cache 中(可能需要替换 Cache 中已有的旧数据),再供 CPU 访问,会产生明显的延迟(称为 "缺失代价")。

Cache 的性能用命中率(Hit Rate) 衡量:命中率 = 命中次数 / 总访问次数。现代 CPU 的 L1 Cache 命中率通常可达 90% 以上,L2/L3 Cache 命中率也在 80%-95% 之间,大幅降低了对主内存的依赖。

三 、cache 和 主存的映射方式

cache 与主存的核心映射方式有三种,核心结论是:直接映射、全相联映射、组相联映射,分别平衡命中率、硬件复杂度和访问速度。

1. 直接映射

  • 主存块按固定规则映射到唯一 cache 块,比如主存块号 mod cache 总块数。
  • 优点是硬件实现简单、访问速度快,无需复杂比较逻辑。
  • 缺点是冲突概率高,多个主存块可能争抢同一 cache 块,命中率较低。

2. 全相联映射

  • 主存块可映射到 cache 中任意一块,无固定限制。
  • 优点是冲突概率极低,命中率最高,能充分利用 cache 空间。
  • 缺点是硬件复杂,需用关联存储器和全比较逻辑,访问速度较慢、成本较高。

3. 组相联映射

  • 先将 cache 分组,主存块先映射到指定组(按规则,如主存块号 mod 组数),再可映射到组内任意块。
  • 优点是兼顾前两种方式,冲突概率低于直接映射,硬件复杂度低于全相联映射。
  • 缺点是性能依赖组大小,组内块数越多(越接近全相联),硬件复杂度越高。

四、cache 替换算法

cache 替换算法的核心是 "当 cache 满时,选择哪个块淘汰以腾出空间",核心结论是:常用经典算法有四种,分别是随机算法、先进先出算法、最近最少使用算法、最不经常使用算法,核心权衡点是命中率、实现复杂度和开销。

1. 随机算法(Random)

  • 随机选择一个 cache 块淘汰,无需记录块的使用信息。
  • 优点是实现最简单、开销最低,无需额外硬件或软件支持。
  • 缺点是命中率最低,可能淘汰刚使用或即将使用的块,性能不稳定。

2. 先进先出算法(FIFO)

  • 按块进入 cache 的先后顺序淘汰,先进入的块优先被淘汰。
  • 优点是实现简单,只需用队列记录块的进入顺序,开销较低。
  • 缺点是未考虑块的实际使用频率,可能淘汰频繁使用的 "老块",命中率中等。

3. 最近最少使用算法(LRU)

  • 淘汰最近一段时间内使用次数最少的 cache 块,基于 "近期未用则远期少用" 的假设。
  • 优点是命中率高,贴合程序局部性原理,性能最优。
  • 缺点是实现复杂,需记录块的使用时序(如用栈、计数器),硬件开销较大。

4. 最不经常使用算法(LFU)

  • 淘汰统计周期内使用次数最少的 cache 块,基于 "使用频率低则未来少用" 的假设。
  • 优点是考虑了块的使用频率,命中率高于随机和 FIFO 算法。
  • 缺点是需统计使用次数,可能淘汰 "曾经高频但近期不用" 的块,且统计开销高于 FIFO。

五、cache 写策略

Cache 写策略的核心目标是 解决 "Cache 块更新后,如何同步主存数据" ,核心分为两大方向:写直达(Write-Through)写回(Write-Back),再配合 "写分配(Write-Allocate)" 或 "非写分配(No-Write-Allocate)" 规则,构成完整的写操作逻辑。

一、核心写策略:写直达 vs 写回

这是决定 "数据同步时机" 的核心策略,直接影响性能、总线开销和硬件复杂度。

1. 写直达(Write-Through,WT)
  • 核心逻辑 :每次写入 Cache 时,同时将数据写入主存(Cache 和主存始终保持数据一致)。
  • 关键规则:若写入的地址已在 Cache 中(写命中):更新 Cache + 同步更新主存;若不在 Cache 中(写缺失):直接写入主存(通常配合 "非写分配",不把主存块调入 Cache)。
  • 优点:① 数据一致性好(Cache 和主存始终同步,无需额外同步机制);② 硬件实现简单(无需记录 Cache 块是否 "脏",无额外判断逻辑);③ 崩溃 / 断电时数据不易丢失(主存已实时更新)。
  • 缺点:① 总线开销大(每次写操作都要访问主存,主存速度慢,拖慢写性能);② 写延迟高(需等待主存写入完成,才能确认写操作结束)。
2. 写回(Write-Back,WB)
  • 核心逻辑 :写入 Cache 时,仅更新 Cache 块,不立即同步主存;只有当该 Cache 块被替换时,才将 "修改过的脏块" 写回主存(未修改的 "干净块" 直接丢弃)。
  • 关键规则:需为每个 Cache 块维护一个 "脏位(Dirty Bit)":标记该块是否被修改过;写命中:更新 Cache + 置位脏位(无需访问主存);写缺失:若替换的是脏块,先将脏块写回主存,再调入新块并更新(通常配合 "写分配")。
  • 优点:① 总线开销小(仅替换脏块时访问主存,多次写同一 Cache 块只需一次主存操作);② 写延迟低(仅操作 Cache,无需等待主存);③ 适配程序 "写局部性"(频繁写同一数据时性能优势极大)。
  • 缺点:① 硬件复杂度高(需维护脏位、设计脏块替换逻辑);② 数据一致性差(Cache 和主存可能不同步,需额外机制处理多处理器 / 多 Cache 场景);③ 崩溃 / 断电风险(未写回主存的脏块数据会丢失,需配合缓存保护机制)。

二、辅助规则:写分配 vs 非写分配

写策略需搭配 "是否将缺失的主存块调入 Cache" 的规则,仅在 "写缺失" 时生效:

规则 写分配(Write-Allocate) 非写分配(No-Write-Allocate)
核心逻辑 写缺失时,先将主存块调入 Cache,再写入 Cache 写缺失时,直接写入主存,不将主存块调入 Cache
搭配的核心写策略 通常与 "写回" 配合(写回 + 写分配是主流组合) 通常与 "写直达" 配合(写直达 + 非写分配更合理)
优势 利用写局部性(后续写同一数据可命中 Cache) 减少 Cache 无效占用(避免调入仅写一次的数据)
劣势 写缺失时额外增加 "调入 Cache" 的延迟和开销 无法利用写局部性(多次写同一数据需反复访问主存)

三、四种常见写策略组合(工程落地主流方案)

组合方式 核心逻辑 适用场景 典型应用
写直达 + 非写分配 写命中:更新 Cache + 主存;写缺失:直接写主存 对一致性要求高、写局部性弱的场景 部分嵌入式设备、简单 IO 缓存
写回 + 写分配 写命中:更新 Cache + 置脏位;写缺失:调块入 Cache→更新→替换时写回主存 写局部性强、追求高性能的场景(主流选择) PC、服务器、手机芯片、高端 SoC
写直达 + 写分配 写命中:更新 Cache + 主存;写缺失:调块入 Cache→更新 + 主存 极少用(兼顾局部性但总线开销仍大) 特殊工业控制芯片
写回 + 非写分配 写命中:更新 Cache + 置脏位;写缺失:直接写主存 极少用(浪费写回的总线优势) 无主流应用

四、核心写策略(写直达 vs 写回)对比表

对比维度 写直达(Write-Through) 写回(Write-Back)
数据一致性 高(Cache 与主存实时同步) 低(仅脏块替换时同步)
总线开销 大(每次写都访问主存) 小(仅脏块替换时访问主存)
写延迟 高(需等待主存写入) 低(仅操作 Cache)
硬件复杂度 低(无需脏位、无复杂替换同步逻辑) 高(需脏位、脏块写回逻辑)
崩溃数据安全性 高(主存已实时更新) 低(脏块可能丢失)
适配局部性 弱(未利用写局部性) 强(充分利用写局部性)
主流程度 非主流(仅简单场景使用) 主流(绝大多数高性能设备选择)

总结

  • 工程落地首选 写回 + 写分配:平衡性能、总线开销和局部性利用,是 PC、服务器、高端芯片的标准配置;
  • 简单场景 / 强一致性需求选 写直达 + 非写分配:牺牲部分性能换低复杂度和高一致性;
  • 写策略的核心 trade-off:性能(写回) vs 一致性 / 复杂度(写直达),需结合场景取舍。
相关推荐
JJCar3 天前
【Cache缓存】分配策略
缓存·cache·多核数据一致性
JJCar4 天前
【Cache缓存】cache的刷新
缓存·cache·多核数据一致性
RAN_PAND5 天前
计算机组成原理实验
网络·计算机组成原理
岑梓铭15 天前
考研408《计算机组成原理》复习笔记,第五章(5)——CPU的【指令流水线(含中断)】
笔记·考研·408·计算机组成原理·计组
ezreal_pan15 天前
架构权衡与实践:基于“约束大于规范”的缓存组件封装
redis·cache·1024程序员节
九丶弟18 天前
SpringBoot的cache使用说明
java·spring boot·spring·cache
JuneXcy18 天前
计算机组成原理实验
计算机组成原理
岑梓铭21 天前
考研408《计算机组成原理》复习笔记,第五章(5)——CPU的【微程序控制器】
笔记·考研·408·计算机组成原理·计组
岑梓铭1 个月前
考研408《计算机组成原理》复习笔记,第七章(1)——I/O接口
笔记·考研·408·计算机组成原理·计组