| 映射方式 | 主存块可放置位置 |
|---|---|
| 直接映射 | 只能映射到固定 Cache 行 |
| 全相联 | 可映射到任意 Cache 行 |
| 组相联 | 折中:n 路组相联,每组 n 行 |
Cache 是位于 CPU 和主存之间的高速小容量存储器,利用程序访问的局部性原理来减少 CPU 访问主存的次数。映射方式决定了主存块如何放置到 Cache 中,是后续地址划分、命中率计算与替换算法的基础。
主存地址 = [标记 Tag][组号/行号][块内偏移 Offset]
命中率 $h = \frac{\text{Cache命中次数}}{\text{总访问次数}}$,缺失率 $= 1 - h$,平均访问时间 $= h \times T_{cache} + (1-h) \times T_{main}$。
Cache 行号 = 主存块号 mod Cache 行数
每个主存块只能映射到 Cache 的固定位置。
| Tag | 行号(Index) | 块内偏移(Offset) |
主存 8 块,Cache 4 行,直接映射:
主存块 0 → Cache 行 0
主存块 1 → Cache 行 1
主存块 2 → Cache 行 2
主存块 3 → Cache 行 3
主存块 4 → Cache 行 0 ← 与块 0 冲突
主存块 5 → Cache 行 1 ← 与块 1 冲突
主存块 6 → Cache 行 2
主存块 7 → Cache 行 3
主存块可以放入 Cache 的任意一行
| Tag(整个主存块号) | 块内偏移(Offset) |
Tag 比较器数量 = Cache 行数
每个比较器比较 Tag 位数的位
→ 硬件成本随 Cache 行数线性增长
Cache 分为若干组(Set),每组包含若干路(Way)
组号 = 主存块号 mod 组数
主存块映射到固定组,但在组内可以放在任意路
| Tag | 组号(Set Index) | 块内偏移(Offset) |
组 0(路 0 和路 1):主存块号 % 2 = 0 的块
组 1(路 0 和路 1):主存块号 % 2 = 1 的块
主存块 0 → 组 0(可放路 0 或路 1)
主存块 2 → 组 0(可放路 0 或路 1)
主存块 4 → 组 0(与块 0 或块 2 冲突)
主存块 1 → 组 1
主存块 3 → 组 1
2 路组相联:每组 2 行
4 路组相联:每组 4 行
8 路组相联:每组 8 行
n 路组相联:每组 n 行
n-way set-associative Cache with m sets:
- 总行数 = n × m
- 每个地址映射到 n 个可能位置(n 路组相联,组内 n 路任选)
| 特性 | 直接映射 | 全相联 | 组相联 |
|---|---|---|---|
| 映射位置 | 唯一 | 任意 | 组内任意 |
| 比较器数 | 1 | 行数 | 路数 |
| 冲突率 | 高 | 低 | 中 |
| 硬件成本 | 低 | 高 | 中 |
| 速度 | 最快 | 慢 | 较快 |
| 典型应用 | L1 Cache | TLB | L2/L3 Cache |
直接映射 Cache:256 行,数据块 32B,地址 32 位
Offset = log₂(32) = 5 位
Index = log₂(256) = 8 位
Tag = 32 - 8 - 5 = 19 位
每行 = 1(有效位) + 19(Tag) + 32×8(数据) = 276 位
总存储位数 = 256 × 276 = 70656 位 ≈ 8.6KB
Cache 容量(纯数据)= 256 × 32B = 8KB
主存 1MB,Cache 8KB,块大小 64B,直接映射
地址 20 位(1MB = 2²⁰,故地址为 20 位)
Offset = log₂(64) = 6 位
Index = log₂(8KB/64B) = log₂(128) = 7 位
Tag = 20 - 7 - 6 = 7 位
主存地址 0x03A7C = 0000 0011 1010 0111 1100(20 位)
Tag(7位) = 0000001 (1)
Index(7位) = 1101001 (105)
Offset(6位)= 111100 (60)
→ 查 Cache 第 105 行,比较 Tag=1,偏移 60 字节
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。