高速缓存组织:数据放在哪一行、满了踢谁
更新时间:2026-09-12。本文是「集成电路大类 · 芯片设计」进阶层(intermediate)数字逻辑第一百零八篇。片上存储层次讲过缓存靠时间/空间局部性让快 SRAM 挡住慢内存;这一篇回答两个具体问题:一个内存块能放到缓存的哪些行?放满了踢掉谁?它和 TLB、MESI 一致性共用同一套 tag/相联硬件。
本文要回答的问题
- 地址为什么切成 offset/index/tag?各用来做什么?
- 直接映射、N 路组相联、全相联差在哪,冲突缺失是什么?
- 命中是怎么一拍判出来的(有效位、tag 比较)?
- write-through 和 write-back、写分配怎么选,脏位有什么用?
- LRU 为什么在高路数时变成「近似 LRU」?
一、地址三分:offset、index、tag
一次访存地址被切成三段:
- offset(块内偏移):最低位,选中一个缓存块(cache line,常见 32/64B)内的字节,块是缓存和内存交换的最小单位;
- index(索引):中间位,选中哪一组/哪一行槽位;
- tag(标记):高位,和槽位里存的标记比较,确认这一行是不是要找的那块。
每行除数据外还存 tag、有效位 V(该行是否装了有效数据)、脏位 D(写回策略下是否被改过),多核时再加 MESI 状态位。
二、三种相联方式
- 直接映射(direct-mapped):内存块只能放在
index指定的唯一行。只需一个比较器,硬件最简单、最快;但两个映射到同一行的块交替使用会互相踢,冲突缺失严重; - 全相联(fully associative):块可放任意行,冲突最少、利用率最高,但每次都要用 CAM 把所有行的 tag 并行比较,面积和功耗大,只适合很小的缓存(如微操作缓存、TLB);
- N 路组相联(N-way set-associative):折中主流。index 先选中一个组,组内有 N 行,这 N 行的 tag 同时比较:命中任意一路即用其数据。N(相联度)越大冲突越少、越接近全相联,但比较器和功耗/访问时间上升——L1 常 8 路左右,LLC 十几~二十路。
地址: [ tag ][ index ][ offset ]
│ 选组
▼
路0: tag0|数据 ┐
路1: tag1|数据 ├─ N 个 tag 同时比较 → 命中选哪一路
... ┘三、命中判定与写策略
- 命中:index 选组后,有效位=1 且某路 tag 与地址 tag 相等即命中;否则缺失,需从下级存储取整行(缺失时用 offset 选字、先填充行);
- 写命中策略:**write-through(写穿透)**每次写都同步到下级,简单但带宽/功耗高,常配写缓冲;write-back(写回)只写缓存、置脏位 D,该行被替换时才写回下级,省带宽但需处理一致性(见 MESI);
- 写缺失:写分配(write-allocate,先把行取上来再写)/非写分配(绕开缓存直接写下级),写回通常配写分配。
四、缺失分类与替换策略
经典 **3C(+1C)**缺失:compulsory 冷启动(第一次见,不可避免,可预取)、capacity 容量(缓存装不下工作集)、conflict 冲突(直接/低相联下争同组,提高相联度可解)、多核再加 coherence 一致性缺失。
组相联一组放满后要选一行踢走:LRU(最近最少用)最优,但 N 路大时维护精确 LRU 序的硬件随路数增长,实践用近似 LRU(树型 PLRU、计数器、 age 位)、随机替换(便宜且性能意外地好)、FIFO。还有针对流式数据的插入/绕过策略。多级缓存间的包含性(inclusive/exclusive/non-inclusive)决定某行是否必须同时存在于上下级,影响 MESI 监听目录和有效容量。
与现有篇目的衔接
- 前置:片上存储层次/局部性、SRAM 单元/灵敏放大器、CAM 匹配线
- 配套:MESI 缓存一致性、MMU/TLB(同样相联查找)、存储体/交叉访问
- 相关:流水线 load 延迟、存储推断/RTL、ECC/可靠存储
总结
一句话总结:高速缓存把地址分成低位块内偏移、中间索引和高位标记,缓存行除数据外还存 tag、有效位、脏位(多核时再加一致性状态);一个内存块的放置位置有三种组织——直接映射用 index 唯一定位一行、硬件最简但不同块争同一行的冲突缺失高,全相联允许放任意行、冲突最少却需 CAM 全表并行比较而昂贵耗电,主流的 N 路组相联先用 index 选组、再让组内 N 行 tag 并行比较,在命中率和面积功耗访问时间间折中(L1 常约 8 路、LLC 十几路以上);命中靠有效位有效且 tag 相等判定,缺失则从下级取整行,写策略分写穿透(每次同步到下级、简单但费带宽)和写回(只写缓存置脏位、替换时才写回、省带宽但要配合缓存一致性),写缺失又分写分配与非写分配;缺失按成因分为冷启动、容量、冲突和多核一致性四类,提高相联度主要消除冲突缺失;替换理想上用 LRU,但高路数时真 LRU 硬件太贵,改用树型 PLRU、计数器等近似 LRU 或随机策略,并通过多级缓存的包含/排他策略影响一致性监听和有效容量。