Cache刷新操作与DMA缓存一致性协议实战 - 第2节

2.1 Cache 行的基本结构

Cache 行(Cache Line)是 Cache 与主存之间数据交换的最小单位。每个 Cache 行不仅存储来自主存的数据块,还包含用于查找和状态管理的辅助字段。

字段宽度(典型)说明
Valid Bit(有效位)1 bit标记该行是否包含有效数据。复位后为 0,加载数据后置 1。
Tag(标签)地址高位用于与 CPU 发出的地址高位比较,判断是否命中。
Data Block(数据块)16~128 字节从主存一次搬入的连续数据。常见嵌入式 Cache 为 32 字节。
Dirty Bit(脏位)1 bit写回策略下,标记该行数据已被修改,尚未写回主存。
关键概念:Cache 行大小直接影响空间局部性利用效率。行过大浪费带宽,行过小增加 Tag 存储开销。ARM Cortex-M7 的 L1 Cache 行大小为 32 字节,x86 通常为 64 字节。
Cache 行结构示意图 Valid 1 bit Tag 地址高位 Data Block 32 字节(典型) Dirty 1 bit 每个 Cache 行 = 有效位 + 标签 + 数据块 + 脏位(写回策略下)

2.2 直接映射(Direct Mapped)

直接映射将主存地址按固定规则映射到唯一的 Cache 行。地址被划分为三个字段:Tag、Index、Offset。

  • Index:选择 Cache 行号。若 Cache 有 2n 行,则 Index 占 n 位。
  • Tag:与 Cache 行中存储的 Tag 比较,判断是否命中。
  • Offset:在数据块内选择具体字节。
优点:硬件简单、查找速度快,只需一次比较。
缺点:多个地址映射到同一行时频繁冲突,导致 Cache 抖动。
直接映射地址分解与查找流程 Tag(高位) Index(行号) Offset(块内偏移) Cache 行阵列 行 0 行 1 … 行 N-1 Tag 比较器 命中 / 缺失

2.3 组相联映射(Set-Associative)

组相联映射是直接映射与全相联的折中方案。Cache 被分为若干组(Set),每组包含多个行(Way)。地址中的 Index 选择组,然后在组内所有行中并行比较 Tag。

  • n 路组相联:每组有 n 个 Cache 行。常见配置:2 路、4 路、8 路。
  • 查找过程:Index → 定位组 → 组内 n 个 Tag 同时比较 → 任意匹配即命中。
  • 替换策略:组内满时需替换,常用 LRU(最近最少使用)或伪 LRU。
实战经验:在 DMA 与 Cache 交互场景中,4 路组相联是性价比最高的选择。冲突率比直接映射降低约 60%,硬件复杂度可控。
4 路组相联 Cache 结构 组 0 Way 0 Way 1 Way 2 Way 3 组 1 Way 0 Way 1 Way 2 Way 3 组 N-1 Way 0 Way 1 Way 2 Way 3 4 路并行比较器 命中 / 缺失

2.4 全相联映射(Fully Associative)

全相联映射允许任意主存块映射到任意 Cache 行。地址中只有 Tag 和 Offset,没有 Index 字段。查找时,CPU 将 Tag 与所有 Cache 行的 Tag 同时比较。

注意:全相联映射的硬件成本极高——需要 N 个比较器(N = Cache 行数),且比较延迟随行数线性增长。在嵌入式系统中,全相联仅用于 TLB(转译后备缓冲器)等小型查找表,不用于数据 Cache。
映射方式冲突概率硬件复杂度查找延迟典型应用
直接映射高低低低端 MCU、简单 Cache
组相联(4 路)中中中ARM Cortex-A 系列、RISC-V 应用处理器
全相联极低极高高TLB、专用查找硬件
全相联映射查找结构 CPU 地址 Tag 行 0 Tag 比较 行 1 Tag 比较 … 行 N-1 Tag 比较 OR 汇聚结果

2.5 映射方式对比与选择指南

在 DMA 与 Cache 一致性设计中,映射方式直接影响刷新操作的粒度和复杂度。

  • 直接映射:刷新操作简单,只需按 Index 遍历。但冲突导致频繁替换,DMA 数据可能被意外踢出。
  • 组相联:刷新时需遍历组内所有 Way。DMA 缓冲区可分散在多个组,减少冲突。
  • 全相联:刷新需遍历所有行,硬件开销大。通常只在 TLB 中使用,数据 Cache 极少采用。
工程建议:对于 DMA 缓冲区,优先将其地址对齐到 Cache 行边界(如 32 字节对齐),并利用组相联特性将缓冲区分散到不同组,可显著降低 Cache 抖动和刷新开销。