计算机组成原理 · 2027 考研计算机 408

第 3 章 存储器层次结构

目标院校:四川大学 / 电子科技大学 | 建议用时:概念 4 小时 + 例题练习 6 小时

本章地位:存储系统是 408 组成原理计算量最大、出题密度最高的一章——Cache—主存映射与命中率、虚拟存储器地址变换几乎年年出题,既考选择题,也多次考与指令系统、CPU 数据通路结合的综合大题。三大计算题型(存储芯片扩展、地址划分、命中率与平均访问时间)本章全部「逐位逐级展开 + 数值核对」,概念题(层次结构、SRAM/DRAM、替换算法、写策略)按选择题口径一次讲透。

3.1 存储器层次与分类

定义对存储器的三项核心要求——速度快、容量大、位价(每比特成本)低——相互矛盾,任何单一器件无法同时满足,因此现代计算机把多种存储器组成层次结构:寄存器 → Cache → 主存 → 辅存。其中两个关键层次:
  1. Cache—主存层次:解决 CPU 与主存速度不匹配的矛盾。全部由硬件实现,对所有程序员透明;
  2. 主存—辅存层次:解决存储系统容量矛盾。由操作系统+硬件共同实现,发展为虚拟存储器,对应用程序员透明(对系统程序员不透明)。
辅存(外存:磁盘、SSD、磁带)中的数据 CPU 不能直接访问,必须先调入主存。
寄存器(CPU 内) Cache(SRAM) 主存(DRAM) 辅存:磁盘 · SSD · 磁带 越上:速度越快、位价越高 越下:容量越大、位价越低 Cache—主存:硬件实现 解决速度矛盾 主存—辅存:OS+硬件 解决容量矛盾
图 3-1 存储器层次「金字塔」:自上而下速度更慢、容量更大、位价更低;两个关键层次分别由硬件与「OS+硬件」实现
易错① 「Cache—主存层次对应用程序员和系统程序员都透明」「主存—辅存层次仅对应用程序员透明」——两句的适用对象别背混;
② 寄存器画在金字塔顶端,但「存储系统的两个层次」特指 Cache—主存 与 主存—辅存;
③ CPU 可以直接访问 Cache 与主存,不能直接访问辅存(辅存与主存之间通过 DMA 等方式交换数据)。

3.1.1 分类方式

分类
  1. 按存储介质:半导体存储器(MOS 型、TTL 型)、磁表面存储器(磁盘、磁带)、光存储器(光盘);
  2. 按存取方式: 随机存储器 RAM(SRAM/DRAM,任一单元存取时间相同,可读可写)、 只读存储器 ROM(正常工作时只读)、 顺序存取存储器 SAM(磁带,物理顺序访问)、 直接存取存储器 DAM(磁盘,先直接定位磁道、再道内顺序找扇区)、 相联存储器(按内容并行检索而不是按地址访问,用于快表 TLB、Cache 查找);
  3. 按信息易失性:易失(RAM 断电即失)与非易失(ROM、Flash、磁盘、SSD)。
一句话记忆「随机」的准确含义是任何一个存储单元的存取时间都相同,与位置无关;磁盘是「直接存取」而不是随机存取,磁带是「顺序存取」——三者按「定位的自由度」递减排序:RAM > DAM > SAM。

3.1.2 存储器性能指标与带宽

三个指标
  1. 存储容量=存储单元个数 × 存储字长(如 64K × 32 位);
  2. 速度:存取时间 \(T_a\)(从启动一次访存到完成)与存取周期 \(T_m\)(连续两次独立访存的最小间隔)。\(T_m\gt T_a\),因为一次访问后还需要恢复时间(如电容充电、放大器复位);
  3. 主存带宽 \(B_m\):单位时间里主存存取的信息量,\(B_m=\dfrac{\text{每次读取的位数}}{\text{存取周期}}\)。
例 1 方法 主存带宽计算(3.3 交叉存储的引入)

某主存数据总线宽度 64 位,存取周期 100ns。求主存带宽;若程序需要的访存带宽为 320MB/s,主存带宽是否够用?

查看解答

每次存取 64 位=8B,周期 100ns:

\[ B_m=\frac{8\text{B}}{100\text{ns}}=\frac{8\text{B}}{100\times10^{-9}\text{s}}=8\times10^{7}\text{B/s}=80\text{MB/s} \]

核对:\(100\text{ns}=10^{-7}\text{s}\),\(8\text{B}/10^{-7}\text{s}=8\times10^{7}\text{B/s}\) ✓。需求 320MB/s 是当前的 4 倍,不够。两条出路:加宽(扩展字长)或 3.3 节的多模块交叉存储器(流水存取);再配合 3.4 节的 Cache 让大多数访存命中高速层。

练习 1

判断正误:(1) Cache—主存层次完全由硬件实现;(2) 磁盘属于顺序存取存储器;(3) 存取周期通常大于存取时间;(4) CPU 可以直接读取 SSD 中的数据。

查看答案

(1) 对,这正是它与主存—辅存层次(OS+硬件)的区别;(2) 错,磁盘是直接存取存储器 DAM,磁带才是 SAM;(3) 对,存取周期=存取时间+恢复时间;(4) 错,SSD 是辅存,数据须先调入主存才能被 CPU 访问。

3.2 SRAM、DRAM 与 ROM

3.2.1 SRAM vs DRAM 与三种刷新

定义SRAM(静态 RAM)用双稳态触发器(典型 6 个 MOS 管)存 1 位,只要不断电信息不丢;DRAM(动态 RAM)用栅极电容存 1 位(1 管 1 电容),电容会漏电,必须定期刷新(典型间隔 2ms)。
对比项SRAMDRAM
存储原理双稳态触发器栅极电容电荷
是否刷新不需要需要(约 2ms 内刷新一遍)
运行速度快慢
集成度低(1 位 6 管)高(1 位 1 管 1 电容)
位价高低
地址引脚不复用行、列地址复用(减半)
典型用途Cache主存
DRAM 三种刷新方式刷新以行为单位(读出一行信息并重新写入,对 CPU 透明):
  1. 集中刷新:在 2ms 间隔的最后集中刷新所有行——存在一段不能读写的「死区」;
  2. 分散刷新:把每个存取周期一分为二(前半读写、后半刷新一行)——无死区,但系统存取周期加倍、速度慢;
  3. 异步刷新:在 2ms 内每隔一段时间刷新一行(行间隔=2ms÷行数)——死区缩短为分散在各处的单个刷新时间,是前两者的折中,应用最广。
例 2 易错 刷新时间计算(集中/分散/异步对比)

某 DRAM 存储体为 128 行 × 128 列,存取周期 0.5μs,刷新间隔 2ms(刷新一行占用一个存取周期)。分别计算三种刷新方式的关键参数。

查看解答

集中刷新:刷新全部 128 行需 \(128\times0.5\mu\text{s}=64\mu\text{s}\),这段是死区;2ms 内其余 \(2000-64=1936\mu\text{s}\) 正常读写,死区占比 \(64/2000=3.2\%\) ✓(\(128\times0.5=64\) ✓)。

分散刷新:系统存取周期 \(=0.5+0.5=1\mu\text{s}\),2ms 内恰好完成 \(2000\) 个「读写+刷新一行」,无死区但速度减半。

异步刷新:行间隔 \(=2000\mu\text{s}\div128=15.625\mu\text{s}\),即每隔约 15.6μs 刷新一行,每次仅占用 0.5μs ✓(\(15.625\times128=2000\) ✓)。既保证 2ms 内刷完全部行,又把死时间摊成 128 个 0.5μs 的小段。

套路总结:刷新按「行」计数——总刷新时间=行数×刷新一行时间,与列数无关。

3.2.2 ROM 家族一览

分类按可编程、可擦除的演进顺序:
  1. MROM(掩膜 ROM):出厂时用掩膜固化信息,此后不能更改;
  2. PROM(可编程 ROM):用户可用熔丝一次性写入,写后不可改;
  3. EPROM(可擦除可编程 ROM):紫外线照射整片擦除后可重写;
  4. EEPROM(电擦除 ROM):电信号擦除,可按字节擦写;
  5. Flash(闪存):电擦除、按块擦除,速度快、密度高(U 盘、SD 卡、主板 BIOS);
  6. SSD(固态硬盘):由 Flash 芯片阵列组成,作辅存使用,非易失、抗震、无机械寻道。
易错① SSD 属于 ROM 家族(Flash 非易失),但逻辑上作辅存——「家族归属」与「层次位置」是两回事;
② Flash 写之前必须先擦除,且擦除以块为单位;EEPROM 才能按字节擦写;
③ 现代「ROM」如 Flash 也能快速随机读,广义上把非易失半导体存储器统称 ROM。
练习 2

下列关于 ROM 与 RAM 的叙述中,错误的是( )
A. MROM 的内容由制造厂在出厂前固化 B. EPROM 用紫外线擦除 C. Flash 擦除以块为单位 D. SSD 断电后数据丢失

查看答案

D。SSD 由 Flash 构成,非易失,断电不丢数据;A、B、C 均为三种 ROM 的正确特性。

3.3 主存组织与 CPU 连接 高频考点

3.3.1 存储芯片与位扩展、字扩展

芯片容量公式存储芯片容量=存储单元数 × 每单元位数(如 1K×8 位)。芯片引脚:地址线根数 \(n=\log_2(\text{单元数})\),数据线根数=每单元位数,另有片选线 \(\overline{CS}\)、读/写控制线。
速算多例1K×8 位 → 10 根地址线、8 根数据线(\(2^{10}=1024\));2K×4 → 11、4;4K×8 → 12、8;16K×1 → 14、1;64K×8 → 16、8 ✓(16K\(=2^{14}\)、64K\(=2^{16}\))。看到容量先拆「2 的幂」,地址线根数立刻出来。
两种扩展
  1. 位扩展(加大字长):8 片 1K×1 位 → 1K×8 位。各芯片地址线、片选线并联,8 根数据线各出 1 位拼成 8 位;
  2. 字扩展(加大字数):2 片 1K×8 位 → 2K×8 位。地址总线 11 根,低 10 位 \(A_9\sim A_0\) 并联接两片,高位 \(A_{10}\) 经译码产生片选信号分别选中两片。
字数、位数都不够时字位同时扩展:先位扩展成组,再对组做字扩展。
例 3 高频考点 用 1K×4 位芯片组成 4K×8 位存储器(字位同时扩展)

用 1K×4 位的 SRAM 芯片构成 4K×8 位的主存模块:(1) 需要多少片芯片?(2) 说明地址线与片选的连接方案,并写出每组芯片的地址范围。

查看解答

(1) 芯片数 \(=\dfrac{4\text{K}}{1\text{K}}\times\dfrac{8}{4}=4\times2=\)8 片 ✓。

(2) 位扩展成组:每 2 片 1K×4 并联成一组「1K×8」——地址线 \(A_9\sim A_0\)、片选线两片并联;一片接数据线 \(D_3\sim D_0\),另一片接 \(D_7\sim D_4\)。字扩展选组:共 4 组,地址总线 12 根,高位 \(A_{11}A_{10}\) 接 2 线-4 线译码器,4 个输出分别作各组片选。

组号\(A_{11}A_{10}\)地址范围(低 10 位全 0 → 全 1)
第 0 组00000H ~ 3FFH
第 1 组01400H ~ 7FFH
第 2 组10800H ~ BFFH
第 3 组11C00H ~ FFFH

核对:每组 1K 个单元=400H 个地址(\(400\text{H}=1024\) ✓),4 组共覆盖 000H~FFFH,恰为 4K ✓。

套路总结:片数=(目标字数÷芯片字数)×(目标位数÷芯片位数);高位地址译码做片选,低位地址并联进芯片。

DRAM 特有的两件事① 地址复用:地址线只给一半宽度,地址分两次送(先送行地址、由 \(\overline{RAS}\) 锁存,再送列地址、由 \(\overline{CAS}\) 锁存),例如 64K×1 芯片只需 8 根地址线(\(16\div2=8\));
② 与 CPU 连接时要外加地址多路器(分时切换行/列地址)、\(\overline{RAS}/\overline{CAS}\) 时序控制和刷新逻辑——SRAM 都不需要。
MAR / MDR主存通过 MAR、MDR 与 CPU 交互:MAR 位数=地址码位数(决定可寻址单元数),MDR 位数=存储字长。如 MAR 16 位、MDR 32 位 → 最大主存 64K×32 位=\(64\text{K}\times4\text{B}=256\text{KB}\) ✓。

3.3.2 双端口 RAM 与多模块交叉存储器

双端口 RAM同一存储体配两套独立的端口(各自的地址、数据、读写控制),两个端口可并行访问不同单元。当两端口同时访问同一单元且至少一个是写操作时发生冲突,由仲裁逻辑暂停其中一个端口(置 busy)。
多模块交叉存储器(低位交叉编址)主存分为 \(m\) 个模块,用地址的低位字段选模块,连续地址分布在不同模块中,可对连续地址流水存取:每个总线传送周期 \(\tau\) 启动一个模块,模块内部按存取周期 \(T\) 完成。流水不断流的条件:模块数 \(m\ge T/\tau\);连续读取 \(m\) 个字的总时间为 \(T+(m-1)\tau\)。(对比高位交叉:高位选模块、连续地址在同一模块,只是容量拼接,无流水收益。)
例 4 真题风格 交叉存储器带宽计算

设主存模块数 \(m=4\),模块存取周期 \(T=8\)ns,总线传送周期 \(\tau=2\)ns,字长 64 位。分别计算流水(低位交叉)与顺序方式读取 4 个连续字的时间,并求两种方式的稳定带宽。

查看解答

时间:流水方式 \(=T+(m-1)\tau=8+3\times2=14\text{ns}\) ✓;顺序方式 \(=mT=4\times8=32\text{ns}\) ✓,一次突发的提速 \(32/14\approx2.29\) 倍。流水不断流条件 \(m\ge T/\tau=8/2=4\),\(m=4\) 恰好满足 ✓。

带宽:流水稳定后每 \(\tau=2\)ns 送出一个 64 位(8B)的字,\(B=\dfrac{8\text{B}}{2\text{ns}}=4\times10^{9}\text{B/s}=4\text{GB/s}\) ✓;顺序方式每 8ns 出一个字,\(B=8\text{B}/8\text{ns}=1\text{GB/s}\)——带宽提升恰为 4 倍(等于模块数)。

套路总结:交叉存储三问——「时间 \(T+(m-1)\tau\)」「条件 \(m\ge T/\tau\)」「带宽=字长/\(\tau\)」,三个公式套完即得分。

练习 3

用 8K×8 位的芯片构成 64K×8 位的主存:(1) 需要几片?(2) 高位地址线如何处理?

查看答案

(1) \(64\text{K}/8\text{K}=8\) 片(字扩展,位不扩展)✓。(2) 地址总线 16 根,低 13 根 \(A_{12}\sim A_0\) 并联接各芯片(\(2^{13}=8\text{K}\) ✓),高 3 位 \(A_{15}A_{14}A_{13}\) 接 3 线-8 线译码器,8 个输出分别作 8 片的片选。

练习 4 方法

低位交叉存储器,模块存取周期 \(T=100\)ns,总线传送周期 \(\tau=25\)ns:(1) 模块数至少取多少才能保证流水不断流?(2) 取该模块数时读取 4 个连续字需多少时间?

查看答案

(1) \(m\ge T/\tau=100/25=4\),至少 4 个模块 ✓。(2) \(T+(m-1)\tau=100+3\times25=175\)ns ✓(顺序方式需 \(4\times100=400\)ns)。

3.4 高速缓冲存储器(Cache) 高频考点

工作原理(局部性)Cache 用 SRAM 实现,存放主存中 CPU 正在使用的活跃块副本,一切调度由硬件完成。其有效性建立在程序访问的局部性原理上:
  1. 时间局部性:刚被访问过的信息,不久后很可能再被访问(循环变量、累加和、热点函数);
  2. 空间局部性:刚被访问信息的邻近信息,很可能接着被访问(数组顺序扫描、指令顺序执行)。
int sum = 0;                    // sum、i 反复读写:时间局部性
for (int i = 0; i < 1000; i++)
    sum += a[i];                // a[i] 顺序访问相邻单元:空间局部性

上面 1000 次加法若每条都直接访主存(100ns 级)代价巨大;而 \(a[0]\sim a[999]\) 连续存放,把整块搬入 Cache 后绝大多数访问在 10ns 级完成——「搬一块、省多次」就是 Cache 的全部动机。

命中率与平均访问时间设访问 Cache \(N_c\) 次、访问主存 \(N_m\) 次,命中率 \[ h=\frac{N_c}{N_c+N_m} \] 平均访问时间有两种口径:
  1. 先访 Cache、未命中再访主存(408 默认口径):\(T=h\,t_c+(1-h)(t_c+t_m)\);
  2. 未命中代价只按主存周期计(Cache 与主存同时启动访问):\(T=h\,t_c+(1-h)\,t_m\)。
例 5 高频考点 命中率与平均访问时间(两种口径)

Cache 存取周期 \(t_c=10\)ns,主存存取周期 \(t_m=100\)ns,命中率 \(h=0.95\)。求平均访问时间。

查看解答

口径一(先访 Cache,未命中再访主存):

\[ T=0.95\times10+0.05\times(10+100)=9.5+5.5=15\text{ns} \]

口径二(未命中只按主存周期计):

\[ T=0.95\times10+0.05\times100=9.5+5=14.5\text{ns} \]

核对:\(0.05\times110=5.5\)、\(0.05\times100=5\) ✓。题干出现「先访问 Cache,未命中后再访问主存」按口径一答 15ns;题干明确「Cache 与主存同时访问/不命中时访问时间为 \(t_m\)」按口径二答 14.5ns。相对无 Cache(100ns),加速约 \(100/15\approx6.7\) 倍——\(h\) 越接近 1,加速越接近 \(t_m/t_c\)。

易错:命中率 95% 时缺失率是 0.05 而不是 0.95;未命中那一部分访问「Cache 时间+主存时间」两段都要算(口径一)。

3.4.1 三种映射方式与地址划分

直接映射主存块只能装入唯一一行:\( \text{Cache 行号}=\text{主存块号} \bmod \text{Cache 行数} \)。主存地址划分为三段:标记|行号|块内地址。实现最简单(只需比较 1 个标记),但两块映射到同一行时互相踢,冲突率高。
例 6 高频考点 直接映射地址划分(逐位展开)

主存地址 16 位,Cache 容量 4KB,块大小 64B,直接映射。求地址三段各占多少位,并对主存地址 0x1234 做完整划分。

查看解答

分段位数:块内地址 \(=\log_2 64=6\) 位;Cache 行数 \(=4\text{KB}/64\text{B}=64=2^{6}\) → 行号 6 位;标记 \(=16-6-6=\)4 位 ✓。

反向核对:主存共 \(2^{16}/64=1024\) 块,\(1024/64=16\) 块映射到同一行,需 \(\log_2 16=4\) 位标记 ✓。

划分 0x1234 \(=0001\,0010\,0011\,0100_2\):高 4 位标记 \(=0001\),中 6 位行号 \(=001000\),低 6 位块内 \(=110100\)。

用十进制核对:\(0\text{x}1234=4660\),块号 \(=\lfloor4660/64\rfloor=72\),块内 \(=4660-72\times64=52\)(\(110100_2=52\) ✓);行号 \(=72\bmod64=8\)(\(001000_2=8\) ✓);标记 \(=\lfloor72/64\rfloor=1\)(\(0001_2=1\) ✓)。

套路总结:地址划分四步——①块内=\(\log_2\)块大小;②行/组数=Cache 容量÷块大小(再÷路数);③标记=地址位数−前两项;④用十进制「块号=地址÷块大小」反向核对。

全相联映射主存块可装入 Cache 任意一行(地址只有「标记|块内」两段,本例标记 10 位)。最灵活、冲突最低、命中率最高,但命中判断要同时比较所有行的标记(相联存储,比较电路贵、速度慢),只适合小容量 Cache。
同参数改为 2 路组相联 ① 直接映射 主存地址 16 位 标记 4 位 行号 6 位 块内 6 位 15…12 11…6 5…0 行号=主存块号 mod 64 只需比较 1 个标记 ② 2 路组相联 标记 5 位 组号 5 位 块内 6 位 15…11 10…6 5…0 组号=主存块号 mod 32 组内 2 行都要比标记 64 行÷2 路=32 组
图 3-2 直接映射与 2 路组相联的主存地址划分对比(主存 16 位、Cache 4KB、块 64B):组相联把 1 个行号位并入标记,组数减半、标记加长
组相联映射组间直接、组内全相联:先按「组号=主存块号 mod 组数」定位唯一组,块可装入组内任意一行。地址划分为标记|组号|块内地址;\(q\) 路组相联每组 \(q\) 行,需比较 \(q\) 个标记。灵活性与硬件代价介于两者之间,是实际机器的主流选择(直接映射即「1 路组相联」,全相联即「整个 Cache 为一组」——两个极端)。
例 7 高频考点 2 路组相联分段演算

主存地址 16 位,Cache 4KB、64 行,块 64B,改用 2 路组相联。求地址分段,并演算主存块 72 落在哪组、标记是多少。

查看解答

分段位数:块内 6 位不变;组数 \(=64\div2=32=2^{5}\) → 组号 5 位;标记 \(=16-5-6=\)5 位 ✓。

演算块 72:组号 \(=72\bmod32=8\),标记 \(=\lfloor72/32\rfloor=2\)(\(72=2\times32+8\) ✓)——块 72 可装入第 8 组的任意一行(2 行之一)。

核对 0x1234(\(=0001\,0\,01000\,110100_2\)):标记取高 5 位 \(=00010_2=2\),组号 \(=01000_2=8\),块内 \(=110100_2=52\),与直接映射演算结果(块 72、块内 52)一致 ✓。

套路总结:从直接映射改 \(q\) 路组相联——组数=行数÷\(q\),组号位数减 \(\log_2 q\),标记位数加 \(\log_2 q\),块内位数不变。

3.4.2 替换算法与写策略

四种替换算法Cache 满后再装入新块必须淘汰旧块(直接映射位置唯一、无需选择,只有组相联/全相联需要替换算法):
  1. 随机 RAND:硬件随机淘汰,电路最简单,命中率无保证;
  2. 先进先出 FIFO:淘汰最早进入的块。可能出现 Belady 异常——分配的行数增多、命中率反而下降(非「栈算法」);
  3. 最近最少使用 LRU:淘汰最久未被访问的块,命中率高、无 Belady 异常(栈算法),实际最常用。实现:堆栈法(维护「最近访问→最久未用」的栈,淘汰栈底)或计数器法(每次访存,命中/新装入行计数器清 0,其余行加 1;淘汰计数值最大的行);
  4. 最不经常使用 LFU:淘汰访问次数最少的块,硬件实现复杂且「新块历史空白」处劣势。
例 8 高频考点 LRU 替换过程逐步模拟(堆栈法)

Cache 有 4 行(全相联),采用 LRU 替换,访问主存块的序列为 1, 2, 3, 4, 1, 2, 5。给出每次访问的命中情况与栈状态(左为栈顶=最近使用),并求命中率;接着再访问块 3 会如何?

查看解答
步访问块结果栈顶 → 栈底
11缺失(装入)1
22缺失2, 1
33缺失3, 2, 1
44缺失4, 3, 2, 1
51命中1, 4, 3, 2
62命中2, 1, 4, 3
75缺失(淘汰栈底 3)5, 2, 1, 4

命中率 \(h=2/7\approx28.6\%\) ✓。核对第 7 步:此时最久未用的是 3(它自第 3 步后一直未被访问),LRU 淘汰 3 而不是 1、2(刚命中过)或 4(第 4 步刚进入)✓。

再访问块 3:缺失(3 已被淘汰),淘汰当前栈底 4,栈变为 3, 5, 2, 1——LRU「保护热点」的特性使 1、2 连续命中留驻。

套路总结:每访问一块——命中则把它「提到栈顶」,缺失则装入并提栈顶、满则删栈底;表中每格都要重排,别只记初始顺序。

写策略Cache 与主存的一致性问题分「写命中」「写不命中」两个层面:
  1. 写命中——写直达(write through):同时写 Cache 与主存,一致性好但写主存频繁(常配写缓冲器);写回(write back):只写 Cache 并置脏位,该行被替换时脏位为 1 才一次性写回主存,速度快、一致性弱;
  2. 写不命中——写分配(write allocate):先把所在块调入 Cache 再写;非写分配(no write allocate):直接写主存、不调块。
搭配习惯:写回法+写分配(后续对该块的写都能命中 Cache);写直达+非写分配(反正每次写都直达主存,调块无益)。
例 9 真题风格 Cache 的总位开销(标记+有效位+脏位)

条件同例 6(主存 16 位地址、Cache 4KB、块 64B、直接映射、写回法)。每行除数据外还有 1 位有效位、1 位脏位。求 Cache 的总存储位数与开销占比。

查看解答

每行:数据 \(64\text{B}=512\) 位,标记 4 位(例 6 结论),有效位 1 位,脏位 1 位,共 \(512+4+1+1=518\) 位。

Cache 共 64 行:总位数 \(=64\times518=33152\) 位 \(=4140\text{B}\approx4.05\text{KB}\) ✓(\(64\times500=32000\),\(64\times18=1152\),合计 33152;\(33152\div8=4140\) ✓)。

管理开销:\((4+1+1)\times64=384\) 位,占比 \(384/33152\approx1.16\%\) ✓。

易错:计算「Cache 总容量」时忘记有效位/脏位,或用「Cache 数据容量 4KB」直接作答——题目问的是总位数,管理位必须计入。

多级与分立 Cache现代 CPU 采用多级 Cache:L1 通常分立为指令 Cache 与数据 Cache(取指与取数并行,配合指令流水线),L2/L3 统一且容量逐级增大、速度逐级变慢、离 CPU 逐级变远。
练习 5 方法

主存地址 32 位,Cache 容量 16KB,块大小 32B,直接映射。求地址三段各占多少位。

查看答案

块内地址 \(=\log_2 32=5\) 位;行数 \(=16\text{KB}/32\text{B}=512=2^{9}\) → 行号 9 位;标记 \(=32-9-5=\)18 位 ✓(\(16384/32=512\) ✓)。

3.5 虚拟存储器

页式虚拟存储器主存—辅存层次由 OS 实现为虚拟存储器:程序员使用比主存大得多的虚拟地址空间。主存与虚存按固定大小划分为页,虚拟地址分为虚页号+页内偏移;页表记录每个虚页对应的实页号(帧号)及控制位:
  1. 有效位=0 表示该页不在主存 → 触发缺页(内中断/故障),由 OS 从辅存调页,必要时先淘汰旧页;
  2. 快表 TLB:页表中活跃表项的 SRAM 副本,相联存储器实现——TLB 命中可免去访问主存中的页表,是「页表的 Cache」。
CPU 虚地址 查快表 TLB 命中? 是 形成实地址 访问主存取数 TLB 命中: 仅 1 次访存 否 访问页表(第 1 次访存) 有效位=1? 是 形成实地址并装入 TLB → 访存 页命中:共 2 次访存 否(缺页) 缺页中断:OS 调页必要时淘汰旧页写回 更新页表与 TLB 访问主存取数 缺页处理需访问磁盘(毫秒级,代价最大),然后回到「查 TLB」路径重新转换地址
图 3-3 页式虚拟存储器地址变换流程:先查 TLB(1 次访存)→ 未命中查页表(2 次访存)→ 缺页则中断调页(代价最大)
例 10 高频考点 TLB 参与下的访存次数

页表常驻主存,TLB 命中率 90%(不考虑缺页)。取一个操作数平均需要访存几次?若每次访存 100ns,平均耗时多少?

查看解答

TLB 命中:查 TLB(不访存)+访问主存取数=1 次;TLB 未命中:访问页表(1 次)+访问主存取数(1 次)=2 次。平均:

\[ \bar N=0.9\times1+0.1\times2=1.1\ \text{次} \]

平均耗时 \(=1.1\times100=110\)ns ✓。对比无 TLB(每次都要先访页表):恒为 2 次、200ns——TLB 把页表开销从「每次多 1 次访存」摊薄为「平均 0.1 次」。

例 11 页式地址变换计算

页面大小 1KB,虚地址 2500 与 800(十进制),页表当前内容:虚页 0 → 实页 5,虚页 1 → 实页 2,虚页 2 → 实页 8(均在主存)。求两个虚地址对应的物理地址。

查看解答

页大小 1KB → 页内偏移 10 位,虚页号=虚地址÷1024 取整,页内偏移=余数。

虚地址 2500:\(2500=2\times1024+452\) → 虚页 2、偏移 452;查页表得实页 8,物理地址 \(=8\times1024+452=8644\) ✓(\(8\times1024=8192\),\(8192+452=8644\))。

虚地址 800:\(800=0\times1024+800\) → 虚页 0、偏移 800;实页 5,物理地址 \(=5\times1024+800=5920\) ✓(\(5120+800=5920\))。

套路总结:页式变换三步——①除页大小拆「页号+页内偏移」;②查页表换页号;③实页号×页大小+原偏移。偏移永远原样照抄。

段式与段页式段式按程序逻辑模块(函数、数组)分段,段长可变:便于共享与保护,但易产生外部碎片;段页式先分段、段内再分页:兼具两者优点,但无快表时一次数据访问需 3 次访存(查段表、查页表、存取数据)。
比较项Cache—主存层次主存—辅存层次
解决的主要矛盾速度容量
实现方式全部由硬件OS+硬件(虚拟存储器)
透明性对所有程序员透明对应用程序员透明、对系统程序员不透明
基本信息单位块(几十~几百 B)页/段(几 KB)
失效处理直接访问主存(几十~百 ns)缺页中断+磁盘调页(ms 级),缺失代价大得多
典型速度差距约 1 个数量级3~4 个数量级以上

3.6 章末自测 真题风格

限时 60 分钟,先做后看答案。难度:★★ 基础 / ★★★ 强化 / ★★★★ 冲刺。所有地址划分、命中率计算务必用十进制反向核对一遍再对答案。

自测 1(选择 · ★★)

下列关于存储器层次结构的叙述中,正确的是( )
A. Cache—主存层次主要解决存储系统的容量问题 B. 主存—辅存层次主要由硬件实现 C. Cache 对应用程序员完全透明 D. CPU 可以直接访问磁盘上的数据

查看答案

C。Cache—主存解决速度矛盾(A 错);主存—辅存由 OS+硬件实现(B 错);辅存数据须先调入主存(D 错)。

自测 2(选择 · ★★)

下列关于 SRAM 与 DRAM 的叙述中,错误的是( )
A. SRAM 依靠双稳态触发器保存信息 B. DRAM 须定期刷新,刷新以行为单位 C. Cache 通常用 DRAM 实现 D. DRAM 芯片的地址引脚通常采用行列复用

查看答案

C。Cache 用 SRAM(快、贵),主存用 DRAM(密度高、位价低);A、B、D 均正确。

自测 3(填空 · ★★★)

某 DRAM 为 128 行 × 128 列,存取周期 0.5μs,刷新间隔 2ms:集中刷新的死区为 \(\underline{\hspace{1cm}}\)μs;改用异步刷新,相邻两次刷新的行间隔为 \(\underline{\hspace{1cm}}\)μs。

查看答案

集中:\(128\times0.5=64\)μs;异步:\(2000\div128=15.625\)μs(约 15.6μs 刷新一行,2ms 内恰好刷完全部 128 行)✓。

自测 4(填空 · ★★★)

用 2K×4 位的芯片构成 16K×8 位的主存,需要 \(\underline{\hspace{1cm}}\) 片;高位地址需接 \(\underline{\hspace{1cm}}\) 线译码器做片选。

查看答案

片数 \(=(16\text{K}/2\text{K})\times(8/4)=8\times2=16\) 片;低位 \(A_{10}\sim A_0\) 共 11 根并联(\(2^{11}=2\text{K}\) ✓),高位 3 根 \(A_{13}A_{12}A_{11}\) 接 3 线-8 线译码器(\(2^{3}=8\) 组 ✓)。

自测 5(选择 · ★★★★ 高频考点)

低位交叉编址的多模块存储器,模块数 4、存取周期 8ns、总线传送周期 2ns,流水方式读取 4 个连续字所需时间为( )
A. 32ns B. 26ns C. 14ns D. 8ns

查看答案

C。\(T+(m-1)\tau=8+3\times2=14\)ns(A 的 32ns 是顺序方式 \(mT\));流水条件 \(m\ge T/\tau=8/2=4\) 恰好满足 ✓。

自测 6(选择 · ★★★★ 高频考点)

主存地址 24 位,Cache 容量 8KB,块大小 16B,直接映射。主存地址「标记|行号|块内地址」的位数依次为( )
A. 11、9、4 B. 9、11、4 C. 10、9、5 D. 11、8、5

查看答案

A。块内 \(=\log_2 16=4\);行数 \(=8\text{KB}/16\text{B}=512=2^{9}\) → 9 位;标记 \(=24-9-4=11\) ✓(\(8192/16=512\) ✓)。

自测 7(计算 · ★★★)

某程序执行中对存储系统共访问 2000 次,其中命中 Cache 1980 次;\(t_c=50\)ns,\(t_m=250\)ns(先访 Cache,未命中再访主存)。求命中率、平均访问时间与相对无 Cache 的加速比。

查看解答

\(h=1980/2000=0.99\);\(T=0.99\times50+0.01\times(50+250)=49.5+3=52.5\)ns ✓(\(0.01\times300=3\));加速比 \(=250/52.5\approx4.76\) 倍 ✓。1% 的缺失率就让平均时间变成命中时间的 5 倍多——缺失的代价被放大。

自测 8(解答 · ★★★★ 冲刺)

Cache 共 4 行,LRU 替换,访问序列为 1, 2, 3, 4, 1, 2, 5, 1, 2, 3。列表模拟全过程并求命中率。

查看解答
步12345678910
访问1234125123
结果缺缺缺缺中中缺(淘汰 3)中中缺(淘汰 4)
栈顶→底12,13,2,14,3,2,11,4,3,22,1,4,35,2,1,41,5,2,42,1,5,43,2,1,5

命中 4 次,\(h=4/10=40\%\) ✓。核对第 7 步淘汰 3、第 10 步淘汰 4:均为当时栈底(最久未用)✓。

自测 9(解答 · ★★★)

页面大小 4KB,虚地址为 0x2A0F,页表中虚页 2 对应实页 5(有效位 1)。求物理地址。

查看解答

页内偏移 12 位:\(0\text{x}2A0F=0010\,1010\,0000\,1111_2\) → 虚页号=高 4 位 \(=0\text{x}2\),偏移 \(=0\text{xA}0F=2575\)(\(2\times4096+2575=10767=0\text{x}2A0F\) ✓)。实页 5:

\[ \text{PA}=5\times4096+2575=20480+2575=23055=0\text{x}5A0F \]

即直接把虚页号 2 换成实页号 5、偏移照抄 ✓。

自测 10(选择 · ★★★)

下列关于 Cache 写策略的说法,正确的是( )
A. 写直达法通常与写分配法搭配 B. 写回法无需设置脏位 C. 写回法中被替换的行仅当脏位为 1 时才写回主存 D. 非写分配法是先把块调入 Cache 再写

查看答案

C。习惯搭配是「写回+写分配」「写直达+非写分配」(A 反了);写回法靠脏位判断是否写回(B 错);非写分配是直接写主存、不调块(D 描述的是写分配)。

3.7 本章考点总结

考点常考题型热度核心方法
存储层次结构与分类选择题★★★Cache—主存:硬件、速度;主存—辅存:OS+硬件、容量;RAM/SAM/DAM/相联辨析
SRAM vs DRAM 与刷新选择题 / 计算★★★★触发器 vs 电容;刷新按行:集中(死区=行数×周期)、分散、异步(2ms÷行数)
存储芯片扩展大题 / 计算★★★★片数=(目标字数÷芯片字数)×(目标位数÷芯片位数);低位并联、高位译码做片选
多模块交叉存储器计算 / 选择★★★流水时间 \(T+(m-1)\tau\);不断流条件 \(m\ge T/\tau\);带宽=字长/\(\tau\)
Cache 三种映射与地址划分大题第一问★★★★★ 必考块内 → 行/组号 → 标记逐位分段;行号=块号 mod 行数;十进制反核
命中率与平均访问时间大题核心★★★★★ 必考\(T=h\,t_c+(1-h)(t_c+t_m)\)(先访 Cache 口径);缺失率放大主存代价
LRU 替换过程大题 / 选择★★★★堆栈法逐步重排:命中提栈顶、缺失装栈顶、满则淘汰栈底
写策略选择题★★★★写回+写分配、写直达+非写分配;脏位决定是否写回
虚拟存储器与 TLB大题 / 选择★★★★虚页号+偏移;TLB 命中 1 次访存、未命中 2 次;缺页代价最大
下一步本章过关标准:11 道例题全部独立重做;自测 10 题中至少 8 题正确;能默写 SRAM/DRAM 对比表、三种映射的地址结构与写策略两对搭配;任给「主存位数+Cache 容量+块大小+路数」能在 1 分钟内完成地址划分并用十进制核对。然后进入 第 4 章 指令系统——指令格式、寻址方式与本章的地址计算一脉相承,大题常与存储系统联合命制。