2. 缓存基础回顾:缓存层次结构、缓存行、写策略与替换策略
在深入对比 x86 与 ARM 的缓存一致性协议之前,必须牢固掌握缓存系统的核心基础。缓存是解决处理器与主存之间“存储墙”问题的关键硬件结构,其设计直接决定了系统的性能与一致性协议的复杂度。本节将系统回顾缓存的层次结构、缓存行、写策略以及替换策略,为后续协议差异分析奠定基础。
2.1 缓存层次结构
现代处理器普遍采用多级缓存(Multi-level Cache)架构,以在速度、容量和成本之间取得平衡。典型的层次结构包含 L1、L2 和 L3 缓存,其核心特征如下:
| 缓存级别 | 典型容量 | 访问延迟(CPU周期) | 位置 | 主要特征 |
|---|---|---|---|---|
| L1 缓存 | 32KB - 128KB | 2 - 4 周期 | 每个核心私有 | 分为指令缓存(L1-I)和数据缓存(L1-D);极低延迟 |
| L2 缓存 | 256KB - 1MB | 10 - 20 周期 | 每个核心私有或共享 | 统一缓存(指令+数据);容量与延迟的折中 |
| L3 缓存 | 2MB - 64MB | 30 - 60 周期 | 所有核心共享 | 最后一级缓存(LLC);用于跨核心数据共享与一致性过滤 |
关键概念: 在缓存一致性协议中,L1 和 L2 通常是“私有缓存”,而 L3 作为“一致性域”的汇聚点。x86 和 ARM 在 L3 的管理方式上存在显著差异,这直接影响监听(Snooping)与目录(Directory)协议的选择。
下图展示了典型的多核处理器缓存层次结构,清晰呈现了私有缓存与共享缓存之间的关系:
2.2 缓存行(Cache Line)
缓存行是缓存与主存之间数据交换的最小单位。理解缓存行的结构对于分析一致性协议中的“伪共享(False Sharing)”问题至关重要。
- 定义: 缓存行是缓存中存储数据的基本单元,通常大小为 64 字节(x86 和 ARM 均采用此标准)。
- 结构: 每个缓存行包含 标签(Tag)、索引(Index)、偏移量(Offset) 以及 数据块(Data Block)。此外,还包含 状态位(如 MESI 状态) 和 一致性标签。
- 对齐: 缓存行在内存中是对齐的,即起始地址是 64 的倍数。这意味着一个 64 字节的缓存行对应内存中一段连续的 64 字节区域。
移植适配警示: 虽然 x86 和 ARM 都使用 64 字节缓存行,但 ARM 架构允许实现定义缓存行大小(如 32 字节或 128 字节)。在移植涉及缓存行刷新的代码时,必须使用架构提供的缓存行大小查询指令(如 x86 的
CPUID 或 ARM 的 CTR_EL0),而非硬编码 64 字节。
下图展示了缓存行的内部结构及其与内存地址的映射关系:
2.3 写策略:写直达与写回
写策略决定了当处理器执行写操作时,数据如何同步到下一级存储。两种基本策略是 写直达(Write-Through) 和 写回(Write-Back)。现代高性能系统几乎全部采用写回策略,但理解两者的差异对于分析一致性协议至关重要。
| 特性 | 写直达(Write-Through) | 写回(Write-Back) |
|---|---|---|
| 写入流程 | 数据同时写入缓存和下一级存储(如 L2 或主存) | 数据仅写入缓存,标记为“脏(Dirty)”,延迟写回 |
| 带宽消耗 | 高(每次写操作都触发总线事务) | 低(仅当缓存行被替换或显式刷回时才写回) |
| 一致性维护 | 简单(下一级存储始终是最新数据) | 复杂(需要脏位和写回机制) |
| 性能特征 | 写操作延迟高,读操作无额外开销 | 写操作延迟低,但写回时可能产生突发延迟 |
| 现代使用场景 | 仅用于特定 I/O 或安全场景 | 所有通用处理器(x86/ARM)的默认策略 |
一致性协议关联: 写回策略是缓存一致性协议复杂性的主要来源。当多个核心共享数据时,一个核心的“脏”缓存行必须被其他核心感知,这催生了 MESI 等协议中的“修改(Modified)”状态和“写失效(Write-Invalidate)”机制。
下图对比了写直达与写回的流程差异:
2.4 缓存替换策略
当缓存已满且需要加载新缓存行时,替换策略决定驱逐哪个现有缓存行。不同的替换策略对缓存命中率和一致性协议行为有直接影响。
2.4.1 常见替换策略
| 策略 | 原理 | 硬件开销 | 命中率 | 一致性影响 |
|---|---|---|---|---|
| LRU(最近最少使用) | 驱逐最长时间未被访问的行 | 高(需要记录访问顺序) | 高 | 可预测性好,但实现复杂 |
| 伪 LRU(pLRU) | 使用二叉树近似 LRU | 中等 | 接近 LRU | x86 和 ARM 均广泛采用 |
| 随机替换 | 随机选择一个缓存行驱逐 | 极低 | 中等 | 不可预测,可能导致一致性流量波动 |
| FIFO(先进先出) | 驱逐最早加载的行 | 低 | 较低 | 可能频繁驱逐共享数据 |
移植适配要点: x86 通常使用复杂的 LRU 或自适应替换策略,而 ARM 更倾向于使用 pLRU 以降低功耗。在移植涉及缓存预取或缓存锁定(Cache Locking)的代码时,需要了解目标架构的替换策略行为,避免性能回退。
2.4.2 替换策略与一致性协议的交互
替换策略不仅影响性能,还直接影响一致性协议的行为:
- 写回触发: 当被驱逐的缓存行处于“修改(Modified)”状态时,必须将其写回下一级存储,这会产生一致性流量。
- 共享行驱逐: 如果被驱逐的行处于“共享(Shared)”状态,通常无需写回,但需要通知其他核心该行不再有效(取决于协议实现)。
- 伪共享加剧: 不恰当的替换策略可能加剧伪共享问题,导致缓存行在不同核心间频繁“乒乓”传输。
下图展示了 LRU 替换策略在 4 路组相联缓存中的工作流程:
2.5 本节总结
缓存基础是理解缓存一致性协议的基石。本节回顾了以下核心概念:
- 缓存层次结构: L1/L2 私有缓存与 L3 共享缓存的协作模式,以及它们在 x86 和 ARM 中的实现差异。
- 缓存行: 64 字节对齐的数据单元,其状态位和标签字段直接参与一致性协议的消息传递。
- 写策略: 写回策略是现代处理器的默认选择,它引入了“脏”状态,是 MESI 协议复杂性的根源。
- 替换策略: LRU 及其变体(pLRU)是主流选择,其行为直接影响一致性流量的模式和频率。