存储器层次结构
考点定位
- 大纲章节:存储器分类与层次结构、主存储器、外部存储器(辅助存储器)、高速缓冲存储器(Cache)、虚拟存储器
- 常见题型:本章是 408 计组大题第一热点(Cache 映射手推、芯片扩展连接几乎隔年一道大题),选择题密集(SRAM/DRAM、刷新、寻址计算、TLB、磁盘参数)
- 考查频率:高(每年 6-10 分,Cache 一项常独占 4-8 分大题)
- 前置知识:MAR/MDR 与编址见计算机系统概述,补码与定点数见数据的表示和运算
- 工程师读者注意:你天天和内存、CPU 缓存打交道,但考试考的是地址位数的机械划分与芯片引脚的精确计算——不背套路,考场上现场推必然超时
一、存储器分类与层次结构
1.1 分类
按三个维度分类(选择题直接考归类):
易错口径:磁盘属"直接存取"存储器(先直接定位到小区域再顺序找),磁带才是"顺序存取"; Cache 与主存都是随机存取。
ROM 家族:MROM(掩膜)→ PROM(一次编程)→ EPROM(紫外线擦除)→ EEPROM(电擦除)→ Flash(闪存,块擦除,固态硬盘/BIOS)。Flash 写前必须先擦除、按块操作,这是选择题细节。
1.2 层次结构:两级映射
自上而下:速度更快、价格更高、容量更小。层次结构靠两个映射支撑:
记忆锚点:Cache—主存层次全靠硬件,所以快;主存—辅存层次靠 OS 介入(缺页要调磁盘),所以慢事件代价大。
1.3 局部性原理与定量分析
时间局部性:刚被访问过的项,很快会再次被访问(循环体、函数反复调用)。 空间局部性:刚被访问项的相邻项,很快会被访问(数组顺序遍历、指令顺序执行)。
定量工具(必背公式):
其中 为访问 Cache 命中次数, 为访问主存(未命中)次数。
平均访问时间(两种口径,看清题目假设):
- 口径一(命中时不访主存,未命中才访):
- 口径二(先访 Cache,未命中再访主存,串行计入 Cache 时间):
408 真题两种口径都出现过,题干会说"先访问 Cache,未命中再访问主存"(口径二)或"Cache 与主存同时访问"(口径一)。没说就默认口径二(多数教材口径)。
例:,,:口径二 ;口径一 。
访问效率 (此题口径二下 )。
二、主存储器
2.1 基本组成与编址
主存由存储体、地址译码驱动电路、读写电路组成,与 CPU 通过 MAR、MDR 交互(回顾计算机系统概述)。
编址口径:按字节编址(每单元 1 B)是默认;若按字编址需说明字长。容量题三件套:单元数 = ,总容量 = 单元数 × 每单元位数,地址空间 = 容量(按字节编址时)。
2.2 SRAM 与 DRAM(高频对比表)
引脚复用细节: 个单元的 DRAM 不引出 根地址线,而是引 根,先送行地址(RAS̅ 有效)再送列地址(CAS̅ 有效)。例:64M×8 位 DRAM,26 位地址只引 13 根地址线。选择题爱考"为什么 DRAM 芯片地址引脚是地址位数的一半"。
2.3 DRAM 刷新(必考小考点)
刷新三口径(以最大刷新间隔 2 ms、刷新以行为单位为前提):
必背结论:①刷新对 CPU 是透明的;②刷新按行进行,只需行地址;③刷新操作读出的是整行信息并再生,不需要片选。
2.4 存储芯片引脚与容量计算(套路化)
芯片规格写法""表示 个单元、每单元 位。引脚计算固定三步:
- 地址线:SRAM 引 根;DRAM 引 根(行列复用)
- 数据线: 根
- 控制线:SRAM 有片选 CS̅、读 OE̅/WE̅(读、写控制共 2-3 根);DRAM 用 RAS̅、CAS̅、WE̅(无片选,选通线兼任)
例题:SRAM 芯片 8K×8 位 → 地址线 根,数据线 8 根。DRAM 芯片 1M×4 位 → 地址 20 位 → 地址线 10 根,数据线 4 根。
反向题:给地址线与数据线反推容量。如某 DRAM 地址线 10 根、数据线 8 根 → 单元数 ,容量 1M×8 位 = 1 MB。
2.5 位扩展与字扩展(大题高频:芯片扩展连接)
- 位扩展(加大字长):单元数够、位数不够。各芯片地址线、片选并联,数据线分段各接一段。
- 字扩展(加大单元数):位数够、单元数不够。各芯片数据线并联,低位地址线共用,高位地址经译码器产生片选。
完整例题(手推全过程):用 4K×4 位 SRAM 芯片构成 16K×8 位主存模块。
第一步,算芯片数:字扩展 倍,位扩展 倍,共 片,分为 4 组、每组 2 片。
第二步,算地址线:系统地址 → 14 根(A13A0);芯片地址 → 12 根,接 A11A0。
第三步,算片选逻辑:高位 A13、A12 两位,接 2:4 译码器,4 路输出分别接 4 组芯片的 CS̅。
第四步,接数据线:每组 2 片位扩展——芯片 1 数据线接 D7D4,芯片 2 接 D3D0,两片共用同一片选与读写控制 WE̅/OE̅。
(映射与译码选择过程属动态内容,待动画化:高 2 位地址取值 → 译码器唯一输出有效 → 选通一组。)
地址空间分配表(考试可直接默画):
易错提醒:地址范围写满 空间;若系统还有其他部件,题目会给首地址,此时"首地址 + 芯片容量 − 1"才是末地址(进制加法别错)。
2.6 提高主存速度简要(选择考点)
- 双端口存储器:两套独立端口(地址/数据/控制)并行读写;同时读同一单元允许,同时写同一单元或一读一写同一单元冲突。
- 多体并行存储器:
- 高位交叉编址(高位选体):顺序存储,一个体连续存满再下一个体,利于扩容,不能流水提速。
- 低位交叉编址(低位选体):连续地址分布在不同体,可流水线方式并行存取。流水条件:体数 ( 为存取周期, 为总线传送周期)。例: 则至少 4 个体,启动后每 时间完成一个字的存取,带宽约提高 倍。
三、程序访问局部性(大题视角)
综合题常给两段循环代码,问 Cache 行为差异。分析套路:
- 写出数据在主存中的存放顺序(C 数组行优先:
a[i][j]与a[i][j+1]相邻) - 按执行顺序展开访问地址序列
- 按块大小分块,数出每块的命中/未命中
经典对比(设每行放 4 个 int,块大小 = 1 行缓存 4 个元素):
版本 A 每块首元素未命中、后 3 个命中(若 Cache 能容下若干行);版本 B 每次跨行访问,若整个数组装不进 Cache,几乎全部未命中。这就是"循环次序影响性能"的原理层解释,工程师直觉要落到地址序列上才得分。
指令本身也有局部性:循环体反复执行体现时间局部性,顺序取指体现空间局部性——所以指令 Cache 命中率通常高于数据 Cache。
四、高速缓冲存储器(Cache)
4.1 基本原理
Cache 全部由 SRAM 构成,由硬件完成全部映射与替换。核心概念:
- 块(block):主存与 Cache 交换信息的最小单位,主存按块划分。
- 行/槽(line/slot):Cache 中存放一个块及其信息的单元,行大小 = 块大小。
- 每行附带标记(tag)(记录该行来自哪个主存块)与有效位(该行数据是否有效,开机时全部无效)。
CPU 给出主存地址 → 按映射规则定位到候选行 → 比较标记与有效位 → 命中则直接取数;未命中则从主存调入块,必要时替换旧行。
4.2 三种映射方式(本章核心,必会手推)
设主存地址共 位、块大小 字节、Cache 共 行。
4.2.1 直接映射:一行对一块,唯一去处
地址划分:标记 位 | 行号 位 | 块内地址 位
特点:硬件最简单、速度快;但冲突多(两个常用块映射到同一行会互相踢),利用率低。直接映射不需要替换算法(候选行唯一)。
4.2.2 全相联:任何块可放任何行
地址划分:标记 位 | 块内地址 位(标记 = 主存块号)。
查找:主存块号与 Cache 所有行的标记同时比较(相联存储器,按内容并行查找)。灵活性最好、冲突最少;但标记比较电路代价大,只适合小容量 Cache(如 TLB 常用全相联/组相联)。需要替换算法。
4.2.3 组相联:组间直接、组内全相联(现代 CPU 通用)
地址划分:标记 位 | 组号 位 | 块内地址 位
先按组号直接定位唯一组,再在组内 路中全相联查找与替换( 路组相联 = 每组 行,总行数 )。 退化为直接映射, 退化为全相联——选择题问"某映射方式可否视为另一种的特例"就是考这个。
4.2.4 表格化手推样例(背下这个流程,大题直接套)
题目设定:主存 1 MB(20 位地址),Cache 数据容量 8 KB,块 32 B。
第一步(分参数):
第二步(地址划分对照):
第三步(给定地址逐位拆解):主存地址 0x35C4A,二进制 20 位:
验算(防错关键):块号 = ;直接映射行号 = ✓;组号 = ✓。位拆法与模运算法互验,大题强烈建议双算一遍。
第四步(命中判断):第 226 行(或第 98 组)有效位 = 1 且标记字段 = 0011010 → 命中,按块内偏移 10 取出数据;否则未命中,从主存第 6882 块调入。
(上述逐位拆解与查找过程可在交互演示中输入任意地址逐步验证:切换映射方式,观察标记/组号/偏移的位级划分。)
4.3 替换算法(未命中且候选行已满时)
LRU 手推套路:维护一个从新到旧的访问序列,命中时该块提到队首,未命中时淘汰队尾。组相联只需在组内维护该序列。
Belady 异常只属于 FIFO(及随机类不利用栈性质的算法),LRU 与 OPT 不会出现——高频判断题。
4.4 写策略(写命中与写未命中两问分开答)
写命中(Cache 与主存都有该块):
- 写直达(write-through):同时写 Cache 与主存。可靠、实现简单;写速度受主存拖累(常用写缓冲缓冲)。
- 写回(write-back):只写 Cache,置脏位(修改位);该行被替换时才写回主存。速度快,但有一致性风险,硬件需脏位。
写未命中(主存有、Cache 无):
- 写分配(write-allocate):先把块调入 Cache 再写。习惯与写回配对。
- 非写分配(no-write-allocate / write-around):直接写主存,不调入。习惯与写直达配对。
选择题高频:"写回法通常配合写分配法""写直达法通常配合非写分配法",问原因:写回本来就指望后续再写同一块,值得调入;写直达每次都同步主存,调入意义小。
多级 Cache 一致性:各级之间也用写直达/写回(如 L1 写直达到 L2,L2 写回到主存)。
4.5 Cache 命中率与平均访问时间
大题流程:展开访问序列 → 按映射方式算每次命中与否(首次访问某块必未命中)→ 数命中率 → 代公式。
Cache 总容量计算(含开销,大题必背):
替换算法位:2 路组相联 LRU 每行 1 位; 路需 位/行;直接映射与随机替换为 0。
例(接 4.2.4 设定,写回 + LRU 2 路组相联):每行开销 = 位,总容量 = 位 = 8544 B。
4.6 Cache 行与主存块对应的手推题套路(大题模板)
标准题干:"主存 X 位地址 / Cache 多大 / 块多大 / 某映射方式,给一串访问地址,问命中情况与命中率。"作答四步:
- 算 、(或 ),写出地址划分与标记位数(先把这张表画在答卷上,后面反复用)
- 对每个访问地址算块号 → 行号/组号(用 验算位拆结果)
- 维护"行号 → 标记(主存块号)"状态表,逐个访问判定命中/替换(LRU 顺序随时更新)
- 统计命中率,如问时间再代入 公式
状态表示例(直接映射,沿用 4.2.4 设定,访问块序列 6882, 1030, 6882, 4126, 1030):
注意第 4 步演示的坑: 要老老实实算(),块号大不能想当然;注意 4126 与 6882 不映射到同一行(226 ≠ 30),二者互不冲突;状态表才是判命中的唯一依据,不能凭"访问过"判断。
五、虚拟存储器
5.1 页式虚拟存储器(工作过程必背)
主存—辅存层次对应用程序员呈现为"虚拟地址空间"。页式虚拟存储器把虚存空间与主存空间都划成固定大小的页(典型 4 KB):
- 虚拟地址(VA)= 虚页号(高位)+ 页内偏移(低位)。例:32 位 VA、4 KB 页 → 虚页号 20 位 + 偏移 12 位。
- 页表:每个进程一张,驻留主存,页表项记录"虚页号 → 实页框号(物理页号)+ 有效位 + 修改位 + 访问位 + 保护位"。页内偏移在虚实转换中不变。
- 地址转换:VA → 查页表(页表基址寄存器 + 虚页号 × 页表项长度)→ 得实页框号 → 拼 页框号 | 页内偏移 = 物理地址(PA)。
- 页表项有效位 = 0 → 缺页(页故障):由 OS 缺页处理程序从磁盘调入(可能触发页面替换),属内中断(故障 fault),处理后重新执行该指令。
- 快表 TLB(见 5.2)加速地址转换。
5.2 TLB(快表)
页表在主存 → 每次取数要多一次访存。TLB 是页表项的小 Cache(SRAM,相联存储器,常为全相联或组相联):
- TLB 内容:页表项的副本(虚页号标记 + 实页框号 + 有效/修改/保护位)。
- 查找:虚页号与 TLB 标记比较(组相联:虚地址的"TLB 组号"位先定位组)→ 命中直接得页框号,不再查页表。
- TLB 缺失 → 查页表:页表命中则把该页表项装入 TLB(TLB 满则按 LRU 替换,被替换项若修改位为 1 要写回页表);页表也缺失才缺页中断。
(TLB→页表→Cache 三级查找为动态内容,待动画化。)
5.3 TLB、页表与 Cache 的访问层次与时间计算
三个部件的容量关系常考:TLB 最小最快(几十至几百项)→ Cache(KB~MB 级)→ 主存/页表(GB 级)→ 磁盘。TLB 与 Cache 都是主存的"缓存",但缓存对象不同:TLB 缓存页表项,Cache 缓存主存块——两者可以同时命中或一齐缺失。
时间计算(分层概率模型,大题模板)。设:TLB 访问时间 、主存访问周期 、Cache 访问时间 ,TLB 命中率 ,Cache 命中率 ,忽略缺页(概率极小):
其中 。
分步拆解:①TLB 命中: + 访 Cache;②TLB 缺失、页表命中: + 访主存查页表 + 访 Cache;③页表缺失:加缺页代价(百万周期级,通常题目让你忽略或单列)。把每种路径的时间与概率列成表再加权求和,是大题标准作答格式。
5.4 段式与段页式(对比即可,考选择)
段式地址越界判断:段内偏移 ≥ 段长 → 越界中断(地址转换中的保护检查,高频选择)。
六、辅助存储器(磁盘,按 408 大纲简要)
6.1 磁盘结构与参数
- 盘面(磁头)→ 磁道(每面同心圆)→ 扇区(最小读写单位,通常 512 B);所有盘面同半径磁道构成柱面。
- 地址三件套:柱面(磁道)号、盘面(磁头)号、扇区号。
- 容量 = 盘面数 × 每面磁道数 × 每道扇区数 × 每扇区字节数。区分非格式化容量(按位密度理论值,更大)与格式化容量(按扇区,实际可用,更小)。
- 磁盘存取速度三指标:寻道时间(磁头移到目标磁道)、旋转延迟(目标扇区转到磁头下,平均 = 半转时间)、传输时间(读写数据本身)。
6.2 访问时间计算
- 平均旋转延迟 = 。速算:7200 rpm → 每转 8.33 ms → 平均 4.17 ms;10000 rpm → 每转 6 ms → 平均 3 ms。
- 传输时间 = (转一圈传一道)。
例:转速 10000 rpm,每道 400 扇区 × 512 B,寻道 6 ms,读一个扇区:旋转延迟 3 ms;每转 6 ms 传一道,一个扇区传输 ms;总计 ms——注意传输时间往往小到可忽略,大头是寻道与旋转。
RAID 简要:RAID 0 条带化提速不冗余、RAID 1 镜像、RAID 5 分布式校验,选择考概念级别即可。
例题
例题 1(模拟题) 某计算机主存按字节编址,地址 32 位,Cache 数据容量 32 KB,块大小 64 B,2 路组相联。(1) 写出主存地址划分;(2) 求标记位数;(3) 采用写回法 + LRU,求每行总开销位数。
解:(1) 块内 位;行数 ,2 路组相联 → 组数 → 组号 8 位;标记 位。地址 = 标记 18 | 组号 8 | 块内 6。(3) 每行开销 = 标记 18 + 有效 1 + 脏 1 + LRU = 21 位。
例题 2(模拟题) 直接映射 Cache,主存 16 位地址,Cache 4 KB,块 16 B。问主存地址 0x1234 映射到哪一行,标记是多少?
解:块内 4 位,行数 → 行号 8 位,标记 位。:标记 0001,行号 0010 0011(35 行),块内 0100。验算:块号 , ✓。
例题 3(模拟题) 用 1K×4 位芯片组成 4K×8 位存储器,需要几片?片选需几位地址译码?
解:字扩展 4 倍、位扩展 2 倍,共 8 片。芯片地址 10 根接 A9~A0,高位 A11A10 共 2 位经 2:4 译码器产生 4 个片选。
例题 4(模拟题) 某程序对某数据结构共访问 1000 次,950 次命中 Cache。Cache 周期 2 ns,主存周期 40 ns,先访问 Cache 未命中再访主存。求命中率与平均访问时间。
解:; ns。
例题 5(模拟题) 关于 DRAM 刷新,下列说法错误的是( )。 A. 刷新以行为单位 B. 刷新对 CPU 透明 C. 集中刷新没有死时间 D. 异步刷新将死时间分散
解:C。集中刷新在刷新期间不能读写,存在死时间(死区);分散刷新才无死区。
例题 6(模拟题) 虚拟地址 32 位,页大小 4 KB,TLB 命中率 99%,TLB 访问 1 ns,查页表(访主存)50 ns,随后访 Cache 命中率 90%,Cache 5 ns,未命中加 50 ns 主存。忽略缺页,求一次取数平均时间。
解:访 Cache 时间 ns。地址转换 ns。总计 ns。
常见坑
- 命中率公式分母是总访问次数,不是主存访问次数;平均访问时间注意题目是"同时访问"还是"先 Cache 后主存"两种口径。
- 直接映射不需要替换算法;只有全相联与组相联的组内才需要。
- 标记位数随映射方式变化:全相联 > 组相联 > 直接映射(同一容量下),别套错。
- Cache 总容量大题必须加标记位、有效位(+ 脏位 + LRU 位),只算数据位是高频扣分点。
- LRU 看"最近是否访问",FIFO 看"进入时间"——命中也会更新 LRU 顺序,但不影响 FIFO 队列。
- 写回配写分配、写直达配非写分配,选项交叉配对必错。
- DRAM 地址引脚是地址位数的一半(行列复用);DRAM 有 RAS̅/CAS̅,没有常规 CS̅。
- 低位交叉编址流水条件体数 ;高位交叉不能提速。
- TLB 命中就不再查页表;TLB 缺失不等于缺页(页表多数仍命中),缺页是页表有效位为 0。
- 页内偏移虚实不变,变的是高位页号部分;段式才有"越界中断",页式没有(页号合法即可)。
- 磁盘平均旋转延迟 = 半转时间;传输时间 = 数据量占整道的比例 × 每转时间。
- 双端口存储器"同时读同一单元"不冲突,"一读一写或双写同一单元"冲突。
自测
- 主存 32 位地址、按字节编址,Cache 64 KB、块 128 B,直接映射。求地址划分与标记位数。
- 某 DRAM 芯片容量 16M×8 位,地址引脚与数据引脚各多少根?
- 写回法为什么需要脏位?写直达法为什么常配写缓冲?
- 2 路组相联 Cache 共 64 行,访问序列为块 5, 8, 5, 133, 8。写出每次命中情况(每组 32 组)。
- 转速 5400 rpm 的磁盘,平均旋转延迟约多少毫秒?寻道 8 ms、读半道数据的传输时间(每转读写一道计)是多少?
- TLB 缺失、页表命中时,地址转换共发生几次访存(不含最终取数,TLB 与页表访问均计)?
自测答案与简析
- 块内 7 位;行数 → 行号 9 位;标记 位。
- 地址 24 位 → 地址引脚 12 根(行列复用);数据引脚 8 根。
- 写回:只写 Cache,脏位标记该行被改过,替换时仅把脏行写回主存,避免无谓写回。写直达:每次写都同步主存,写慢,用写缓冲让 CPU 不必等主存写完。
- 组号 = 块号 mod 32:块 5 → 组 5;块 8 → 组 8;块 133 → → 组 5。序列:5 未命中装入组 5;8 未命中装入组 8;5 命中(更新 LRU);133 映射到组 5,该组 2 路只占了 1 路(块 5),尚有空位,未命中但无需淘汰,直接装入;8 命中。共 2 次命中,命中率 40%。错因提醒:看见"同组"就急着替换是高频错误——先看组内是否还有空行。
- 每转 ms,平均旋转延迟 ms;半道传输 ms;总 ms。
- 1 次主存访问(读页表)。TLB 是 CPU 内 SRAM 部件,其访问不占主存访存周期;若题目口径把 TLB 访问也计入"访存",才需要加上。