主存与cache

主存与Cache的地址结构

Cache 是为解决 CPU 与主存速度不匹配 问题而设计的高速缓冲存储器,其地址结构的设计核心是实现主存块到 Cache 块的高效映射,同时配合标记校验、替换策略、写策略完成数据的快速存取。

一、核心前置原理(地址结构设计的依据)

  1. 局部性原理:Cache 存在的根本前提,包括时间局部性(近期访问过的数据大概率被再次访问)和空间局部性(访问某数据时,其相邻数据大概率被访问)。

  2. 块大小对齐:主存和 Cache 均被划分为大小相等的块(Block),块大小通常是 2 的整数次幂(如 16B、32B、64B),块内偏移量字段的位数由块大小决定,且主存与 Cache 的块内偏移量完全相同。

  3. 地址位数的决定因素

    • 主存地址位数 = $\log_2(主存总容量)$ = 地址总线位数,与机器字长无关;
    • Cache 地址位数 = $\log_2(Cache总容量)$,仅由 Cache 自身容量决定。

二、三种映射方式的地址结构与实现细节(考研必考)

设:主存总容量 $M=2^m$ 字节,Cache 总容量 $C=2^c$ 字节,块大小 $B=2^b$ 字节;则:主存块数 $= 2^{m-b}$,Cache 块数 $= 2^{c-b}$。

映射方式 地址结构拆分(主存地址 + Cache 地址) 映射逻辑与硬件实现 优缺点 适用场景
直接映射 主存地址:$\underbrace{主存块标记}{m - (c - b) - b = m - c}\text{位} + \underbrace{Cache块号}{c - b}\text{位} + \underbrace{块内偏移量}{b}\text{位}$
Cache 地址:$\underbrace{Cache块号}
{c - b}\text{位} + \underbrace{块内偏移量}_{b}\text{位}$
1. 映射规则:主存块 $i$ 只能映射到 Cache 块 $i \mod 2^{c-b}$
2. 硬件支撑:标记阵列(每行存储 1 个主存块标记 + 有效位),有效位表示该 Cache 块是否有效
优点:硬件实现简单,寻址速度快
缺点:冲突率高(多个主存块竞争同一个 Cache 块)
小容量 Cache
全相联映射 主存地址:$\underbrace{主存块号}{m - b}\text{位} + \underbrace{块内偏移量}{b}\text{位}$
Cache 地址:$\underbrace{Cache块号}{c - b}\text{位} + \underbrace{块内偏移量}{b}\text{位}$
1. 映射规则:主存任意块可映射到 Cache 任意块
2. 硬件支撑:相联存储器(按内容查找,同时比对所有 Cache 块的标记)
优点:冲突率最低
缺点:硬件成本高,寻址速度慢
块数极少的 Cache
组相联映射(折中方案,高频考点) 分组规则:将 Cache 分为 $G=2^g$ 组,每组含 $r=2^{c - b - g}$ 个块($r$ 称为相联度
主存地址:$\underbrace{主存块标记}{m - g - b}\text{位} + \underbrace{组号}{g}\text{位} + \underbrace{块内偏移量}{b}\text{位}$
Cache 地址:$\underbrace{组号}
{g}\text{位} + \underbrace{组内块号}{c - b - g}\text{位} + \underbrace{块内偏移量}{b}\text{位}$
1. 映射规则:主存块 $i$ 映射到 Cache 组 $i \mod 2^g$,组内任意块均可存放
2. 硬件支撑:组内采用相联查找,组间采用直接查找
优点:冲突率低于直接映射,速度快于全相联映射
缺点:硬件复杂度随相联度 $r$ 增加而上升
中大容量 Cache(考研常考 2 路/4 路组相联)

关键补充:标记阵列的作用

标记阵列是 Cache 寻址的核心硬件,每行对应一个 Cache 块,存储的信息包括:

  • 标记位:存储主存块标记(用于校验当前 Cache 块是否是 CPU 所需的主存块);

  • 有效位:0 表示该 Cache 块无有效数据,1 表示有效;

  • 脏位(修改位):用于写策略,1 表示该 Cache 块数据被修改过,替换时需写回主存;

  • LRU 位/计数器:用于替换策略,记录块的使用情况。

三、Cache 的寻址流程(地址结构的实际应用)

组相联映射为例,CPU 访问数据的步骤:

  1. 拆分主存地址:得到「主存块标记 + 组号 + 块内偏移量」;

  2. 组寻址:根据「组号」找到 Cache 对应的组;

  3. 组内相联查找:将组内所有块的标记与「主存块标记」比对;

    • 命中:若找到匹配标记且有效位为 1,直接用「组内块号 + 块内偏移量」组成 Cache 地址,读取数据;
    • 未命中:若未找到匹配标记,或有效位为 0,发起缺页(块)中断,从主存调入对应块到 Cache 组内,再读取数据(若组内已满,需执行替换策略)。

四、配套核心策略(与地址结构联动)

  1. 替换策略:Cache 块满时,选择淘汰哪个块,与地址结构无关,但直接影响 Cache 命中率

    • 常见策略:LRU(最近最少使用)(考研高频)、FIFO(先进先出)、随机替换;
    • 实现:LRU 需在标记阵列中记录块的使用时间戳,组相联映射中组内独立执行 LRU。
  2. 写策略:解决 Cache 与主存数据一致性问题,核心是「何时将修改后的 Cache 块写回主存」

    • 写直达:写 Cache 的同时写主存,优点是一致性好,缺点是速度慢;
    • 写回:仅当 Cache 块被淘汰时才写回主存,需配合脏位,优点是速度快,缺点是一致性稍差;
    • 写分配 vs 非写分配:未命中时,写分配会调入主存块到 Cache 再写,非写分配直接写主存。

五、考研常考计算(地址结构字段位数计算)

例题:主存容量 4GB($2^{32}$ B),Cache 容量 16KB($2^{14}$ B),块大小 64B($2^6$ B),采用 4 路组相联映射,计算主存地址各字段位数。

解:

  • 主存地址总位数 $m=32$ 位,块内偏移量位数 $b=\log_264=6$ 位;

  • Cache 块数 $= 2{14}/26=2^8$ 块,4 路组相联 → 组数 $G=28/4=26$ → 组号位数 $g=6$ 位;

  • 主存块标记位数 $= m - g - b=32-6-6=20$ 位;

  • 主存地址结构:$\boxed{20位标记} + \boxed{6位组号} + \boxed{6位块内偏移量}$。

六、与之前知识点的关联

  1. 主存地址位数 = 地址总线位数,与机器字长无关;

  2. 机器字长是 CPU 一次处理的数据位数,若机器字长 32 位,一个字占 4B,则块内偏移量若为 6 位(块大小 64B),可存放 16 个 32 位字;

  3. 直接寻址的地址字段位数 ≠ 主存地址位数,前者是指令格式中分配的地址位数,后者是主存的物理地址位数。