1. Cache 基础概念:作用、层次结构与组相联

Cache(高速缓存)是位于 CPU 与主存之间的高速小容量存储器,用于弥合处理器与 DRAM 之间的速度鸿沟。在 x86 与 ARM 平台上,Cache 的刷新指令、策略和硬件实现存在显著差异,但底层原理一致。本节从三个核心维度建立 Cache 基础:作用、层次结构、行与组相联。

1.1 Cache 的核心作用

Cache 利用时间局部性(近期访问的数据很可能再次被访问)和空间局部性(访问某地址后,邻近地址很可能被访问)来减少平均访存延迟。

对比项 CPU 寄存器 Cache (L1/L2/L3) 主存 (DRAM)
典型容量 几十~几百 Byte 32KB~几十 MB 4GB~512GB
访问延迟 ~1 个时钟周期 3~40 个时钟周期 100~300 个时钟周期
带宽 极高 高 中低
数据持久性 掉电丢失 掉电丢失 掉电丢失
关键认知:Cache 对程序员是透明的(硬件自动管理),但在多核、DMA、外设共享内存场景下,Cache 一致性问题必须通过显式刷新指令解决——这正是本课程移植适配的核心痛点。

1.2 Cache 层次结构(L1 / L2 / L3)

现代 CPU 采用多级 Cache 结构,典型配置如下:

  • L1 Cache:每个核心私有,分为指令 Cache(L1-I)和数据 Cache(L1-D),容量通常 32KB~64KB,延迟 3~5 周期。
  • L2 Cache:每个核心私有或两个核心共享,容量 256KB~1MB,延迟 10~20 周期。
  • L3 Cache:所有核心共享,容量 2MB~64MB,延迟 30~40 周期,用于跨核数据共享与一致性。
Cache 层次结构示意图 Cache 层次结构(多核系统) Core 0 L1-I / L1-D L2 Cache Core 1 L1-I / L1-D L2 Cache Core 2 L1-I / L1-D L2 Cache Core 3 L1-I / L1-D L2 Cache L3 Cache(共享) 主存(DRAM) L1/L2 为每个核心私有,L3 全局共享;容量逐级增大,延迟逐级增加
移植注意:x86 通常使用 MESI 协议族维护 L1/L2 与 L3 的一致性;ARM 使用 MOESI 或 ACE 协议。刷新指令(如 x86 的 CLFLUSH、ARM 的 DC CVAC)作用范围不同,必须明确目标层级。

1.3 Cache 行与组相联

Cache 以行(Cache Line)为最小操作单元,典型大小为 64 字节(x86 与 ARM 均如此)。主存地址被划分为:标签(Tag)、索引(Index)、块内偏移(Offset)。

1.3.1 三种映射方式

映射方式 描述 优点 缺点
直接映射 每个主存块只能映射到 Cache 中唯一行 硬件简单、查找快 冲突率高,Cache 利用率低
全相联 任何主存块可映射到任意 Cache 行 冲突率最低 硬件复杂,比较器多,功耗高
组相联 Cache 分为若干组,每组包含 N 行(N 路组相联) 冲突率与硬件复杂度折中 比直接映射稍复杂

现代 CPU 普遍采用 N 路组相联(N-Way Set-Associative),典型值:L1 为 4~8 路,L2 为 8~16 路,L3 为 12~20 路。

1.3.2 地址分解示例(64 字节行,4 路组相联,32KB Cache)

Cache 大小 = 32KB = 32768 字节
行大小    = 64 字节
总行数    = 32768 / 64 = 512 行
组数      = 总行数 / 路数 = 512 / 4 = 128 组

地址位分配(32 位地址):
[31:7]  Tag(25 位) | [6:0]  Index(7 位,128 组) | [5:0]  Offset(6 位,64 字节)
4 路组相联 Cache 结构 4 路组相联 Cache 结构 地址分解:Tag(25 位) | Index(7 位,128 组) | Offset(6 位) 组 0 路 0 路 1 路 2 路 3 组 1 路 0 路 1 路 2 路 3 ...... 组 127 路 0 路 1 路 2 路 3 Index 选择组,组内 4 路并行比较 Tag;命中则返回对应 Cache Line 数据 替换策略:LRU(最近最少使用)或伪 LRU,决定新行写入哪一路

1.4 Cache 行状态与一致性基础

在多核系统中,同一 Cache 行可能出现在多个核心的私有 Cache 中。MESI 协议定义了四种行状态:

  • M(Modified):行被修改,仅本核心持有,与主存不一致。
  • E(Exclusive):行未被修改,仅本核心持有,与主存一致。
  • S(Shared):行未被修改,多个核心持有,与主存一致。
  • I(Invalid):行无效,不可使用。
刷新操作关联:Cache 刷新指令(如 x86 CLFLUSH、ARM DC CIVAC)的本质是将指定地址的 Cache 行写回主存并置为 Invalid 状态。在移植时,必须确认目标平台是否支持“写回+失效”原子操作,以及是否影响相邻行。

1.5 本节要点总结

概念 关键数值 / 特征 对移植的影响
Cache 行大小 64 字节(x86/ARM 统一) 刷新粒度固定,对齐要求一致
组相联路数 L1: 4~8 路;L2: 8~16 路 影响伪共享(False Sharing)概率
MESI 状态 M/E/S/I 刷新指令需考虑状态转换
L1/L2 私有 每个核心独立 跨核刷新需广播或使用 L3