第 5 章 存储器层次结构¶
依据:袁春风《计算机组成原理》(2016 年版)第 5 章及配套自考大纲。下文编号指大纲“考核内容与考核要求”;教材算例为学习辅助,不是真题。
复习导航:大纲要求与笔记位置¶
| 大纲条目 | 层次 | 位置 | 学完应能做到 |
|---|---|---|---|
| 1 存储器概述 | 领会 | 第 1 节 | 说明分类方式、主存基本结构、容量与存储周期的概念、层次化结构 |
| 2 半导体随机存取存储器 | 领会 | 第 2 节 | 说明 SRAM 与 DRAM 特点、刷新、SDRAM 读写、突发传输与行缓存 |
| 3 芯片扩展及其与 CPU 的连接 | 领会、简单应用 | 第 3 节 | 说明扩展方式与内存条组织,计算容量、芯片数、引脚数与地址划分 |
| 4 半导体只读存储器和 Flash | 领会 | 第 4 节 | 说明各类 ROM 特点及 Flash 的读写原理 |
| 5 高速缓冲存储器 Cache | 识记、领会、简单应用、综合应用 | 第 5 节 | 计算容量、命中率、平均访问时间、映射行号,分析访存过程的命中情况 |
| 6 虚拟存储器 | 识记、领会、简单应用、综合应用 | 第 6 节 | 说明页表功能、缺页处理与 TLB,完成地址转换,分析访存全过程 |
第 5、6 条是本章仅有的两条同时含综合应用的条目,要求综合运用映射、替换、写策略或页表、Cache 知识分析完整访存过程。其余条目以领会为主,其中第 3 条含简单应用。
本章学习目标¶
计算机需要兼顾访问速度、容量和成本,因此利用局部性原理组织“寄存器—Cache—主存—外存”层次,让较小、较快的上层存储器保存近期常用内容。本章讨论各层的结构及数据如何在层间流动。
第 1–4 节介绍主存与芯片,包括 SRAM/DRAM、SDRAM、字位扩展、ROM 和 Flash;第 5 节分析 Cache 映射、替换、写策略与命中率;第 6 节连接虚拟存储、TLB、页表与 Cache。计算重点是两种地址切分:物理地址的“标记+组索引+块内偏移”,以及虚拟地址的“虚页号+页内偏移”。
1 存储器概述(1,领会)¶
不同存储介质的速度、容量与每比特成本存在差异,计算机通过层次化存储体系进行权衡:CPU 寄存器、高速缓存(常分 L1/L2/L3)、DRAM 主存,以及磁盘或 SSD 辅存。其有效性依赖时间局部性(近期访问过的内容可能再次访问)和空间局部性(相邻地址可能连续被访问),但具体命中情况仍取决于程序。
计算存储容量或分析性能前,先区分以下基本概念:
- 存储容量 \(=\) 存储单元个数 \(\times\) 每个单元的位数(存储字长)。比如标称
8K × 8 位的芯片有 \(8 \times 1024 = 8\,192\) 个单元、每单元 8 位(1 B),总容量为 \(8\ \text{KB}\);而8K × 16 位则是 \(16\ \text{KB}\)。 - 编址单位与地址线根数:32 根地址线若按字节编址,可寻址 \(2^{32}\ \text{B} = 4\ \text{GB}\);若改为按字编址(比如每字 4 B),同样 \(2^{32}\) 个字单元对应的总容量就是 \(16\ \text{GB}\)。
- 存取时间与存储周期:存取时间(访问时间)指启动读写到数据输出或写入完成的时间;存储周期指连续启动两次独立操作所需的最短间隔。DRAM 读出后还需恢复等操作,因此存储周期通常大于存取时间。
- 按存取方式分类:随机存取(RAM/ROM)的访问时间通常与单元位置无关,并非随机挑选地址;顺序存取如磁带,需依次查找;直接存取如磁盘,先定位区域再等待目标扇区;相联存取(CAM,如 TLB)则按内容并行匹配表项。
2 半导体随机存取存储器(2,领会)¶
Cache 通常采用 SRAM,主存通常采用 DRAM。两者都支持随机存取,但基本存储单元与维护方式不同:
| 项目 | SRAM(静态 RAM) | DRAM(动态 RAM) |
|---|---|---|
| 存储元原理 | 双稳态触发器(6 个晶体管)锁存 0/1 | 栅极电容上的电荷多少表示 0/1(仅 1 个晶体管+1 个电容) |
| 是否需要刷新 | 只要不断电就能一直保持,不需要刷新 | 电容会自然漏电,且读出是破坏性的,必须周期性刷新(读后重写) |
| 速度与集成度 | 速度快、集成度低、功耗大、价格贵 | 速度较慢、集成度高、功耗低、价格便宜 |
| 典型用途 | CPU 内部或片外高速缓存 Cache | 计算机主存(内存条) |
DRAM 通过行列地址分时复用减少引脚。阵列为 \(2^r \text{ 行} \times 2^c \text{ 列}\) 时,片内地址共 \(r + c\) 位,行、列地址可分时送入同一组引脚,并分别由 \(\overline{\text{RAS}}\)、\(\overline{\text{CAS}}\) 锁存。因此地址引脚数为 \(\max(r, c)\),当 \(r = c\) 时减半。刷新按行保持电荷,每行需在规定间隔(如 \(64\ \text{ms}\))内完成刷新,由控制器管理,无需 CPU 逐项重写全部数据。
SDRAM(同步 DRAM)按时钟组织操作:激活某行并将数据读入行缓存(Row Buffer),再按列地址访问,换行前进行预充电(Precharge)。行命中可省去重新激活的开销,突发传输(Burst)则在给定首地址后连续传输数据。DDR / DDR2 / DDR3结合双沿传输及 2 位、4 位、8 位预取提高传输率。DDR3-1333 的标称速率已是每秒 \(1333\ \text{M}\) 次传输,64 位通道带宽按 \(1333\ \text{M} \times 8\ \text{B}\) 计算,不再乘 2。
3 芯片扩展与 CPU 连接(3,领会、简单应用)¶
单块存储芯片的字数或位数不够拼出整块主存时,得拿多块芯片做扩展连接:
- 位扩展(位数不够、字数够):所有芯片的地址线、片选线 \(\overline{\text{CS}}\) 和读写控制线全部并联在一起,各自的数据线分别接数据总线的不同位(比如拿两片
8K × 8 位并联拼成8K × 16 位),选通时所有芯片同时读写。 - 字扩展(字数不够、位数够):所有芯片的片内地址线、数据线和读写线并联,多出来的高位地址线送进译码器产生各芯片独立的片选信号 \(\overline{\text{CS}}_i\),同一时刻只点亮其中一片。
- 字位同时扩展:先把 \(W / w\) 片芯片做位扩展绑成一组凑够位宽,再拿 \(M / m\) 组做字扩展凑够总字数。设目标主存容量为 \(M \text{ 字} \times W \text{ 位}\),单片容量为 \(m \text{ 字} \times w \text{ 位}\):
算例:用 8K × 8 位 芯片拼成 32K × 16 位 存储器。每组需位扩展 \(16 / 8 = 2\) 片,共需字扩展 \(32\text{K} / 8\text{K} = 4\) 组,总计 \(2 \times 4 = 8\) 片芯片。32K 个字需要 15 根字地址线(\(A_{14}\dots A_0\)):低 13 根(\(A_{12}\dots A_0\),对应 \(8\text{K} = 2^{13}\))并联接所有芯片做片内寻址,高 2 根(\(A_{14}A_{13}\))送 2-4 译码器选通 4 组芯片中的一组。
4 ROM 和 Flash(4,领会)¶
常规 RAM 断电后不能保留内容,启动固件需存放在非易失存储器中。教材按可改写方式介绍 ROM 家族:掩膜 ROM 出厂时固定;PROM 可一次编程;EPROM 可经紫外线整片擦除后重写;EEPROM 支持电擦除重写。
Flash(闪存)是电擦写非易失存储器。教材区分了可支持芯片内直接执行代码的 NOR Flash,以及常用于 U 盘、SSD 和手机存储的 NAND Flash。NAND 通常按页读取和编程,按块擦除;擦除把块恢复为全 1,编程使选定位从 1 变为 0。需要把已编程的 0 恢复为 1 时,必须先擦除所在块,不能像 SRAM/DRAM 那样任意原地覆盖。SSD 因此需要异地更新、垃圾回收和磨损均衡。NOR 的读写粒度应另看器件规则,不把 NAND 的页操作方式套到所有 Flash 上。
5 高速缓冲存储器 Cache(5,识记、领会、简单应用、综合应用)¶
5.1 局部性与基本概念¶
Cache 通常由高速 SRAM 构成,位于 CPU 与 DRAM 主存之间。它利用时间局部性保留近期使用的指令和数据,利用空间局部性在缺失时调入相邻的一整块数据,即主存块/Cache 行,如 32 B 或 64 B。
算 Cache 性能就两条核心公式:设命中次数与总访问次数之比为命中率 \(h\),则缺失率(未命中率)\(m = 1 - h\)。设命中时访问 Cache 耗时 \(T_c\)(命中时间),缺失时额外付出的主存调块时间为缺失损失 \(T_m\),则 CPU 的平均访存时间(AMAT)为:
若题干给的不是额外损失 \(T_m\),而是整次缺失的总耗时 \(T_{\text{miss}}\),则按 \(h \times T_c + (1 - h) \times T_{\text{miss}}\) 加权计算,避免重复计入 \(T_c\)。
5.2 映射与地址划分¶
映射方式决定主存第 \(k\) 号块可放入 Cache 的哪些行。设主存按字节编址、地址为 \(A\) 位,Cache 数据区为 \(C\) 字节,每行 \(B = 2^b\) 字节,采用 \(E\) 路组相联,则总行数 \(= C / B\),组数为 \(S = \dfrac{C}{B \times E} = 2^s\)。地址从低位到高位划分为块内偏移 \(b\) 位、组索引 \(s\) 位、标记 \(t = A - s - b\) 位;直接映射时,组索引即行号:
| 映射方式 | 主存块能放进哪儿 | 硬件查找与冲突特点 |
|---|---|---|
| 直接映射(\(E=1\)) | 只能放进唯一固定的第 \((\text{块号} \bmod \text{总行数})\) 行 | 只需 1 个比较器、无需替换算法;但同余的两个热块会反复把对方顶掉(冲突缺失高) |
| 全相联映射(\(S=1\)) | Cache 里任意一行空着都能放(无中间索引字段,地址只切“标记+块内偏移”) | 空间利用率最高、冲突最少;但查找时得拿所有行的标记同时并行比对,硬件昂贵 |
| \(E\) 路组相联 | 先按 \((\text{块号} \bmod \text{组数 } S)\) 固定进哪一组,组内的 \(E\) 行当中任意一行都能放 | 兼顾直接映射的简单与全相联的低冲突,每组配 \(E\) 个比较器与组内替换位 |
例:32 位地址、Cache 数据区 4 KB、块 16 B、2 路。先把字段数算出来。块 16 B 给 4 位偏移;数据区 4×1024 ÷ 16 = 256 行,2 路相联即 128 组,索引 7 位;剩下 32−7−4 = 21 位归标记。
拿地址 12345678H 走一遍,三步。
第一步,展开成二进制。 十六进制一位摊成四位,从高位到低位铺开:
1 2 3 4 5 6 7 8
0001 0010 0011 0100 0101 0110 0111 1000
第二步,从右往左划线。 先切最右 4 位作块内偏移,再往左切 7 位作组索引,剩下的全是标记:
- 块内偏移 = 最右 4 位
1000= 8; - 组索引 = 再往左 7 位
1100111= 67H = 103; - 标记 = 余下 21 位
000100100011010001010= 2468AH,即地址右移 \(7+4=11\) 位后的值。
第三步,重新聚合核账。 21+7+4 = 32 位;各字段必须按原来的位宽拼接:
000100100011010001010 | 1100111 | 1000
标记 21 位 | 索引 7 位 | 偏移 4 位
数值核对为 \(149\,130 \times 2^{11} + 103 \times 2^4 + 8 = 305\,419\,896\),转回十六进制就是 12345678H。不能把十六进制表示 2468A、67、8 直接连成字符串:21 位标记和 7 位索引都没有对齐到 4 位边界。
本例索引为 7 位,跨越两个十六进制字符:取第 6 个字符 6(0110)的低 3 位,再接第 7 个字符 7(0111)的 4 位。字段边界未对齐 4 位时,应按二进制切分,不能直接按十六进制字符截取。
算 Cache 总容量(总位数)(如本章习题 8)时,先区分数据区与管理信息。设共 \(L\) 行,每行数据区为 \(B\) 字节,标记为 \(t\) 位,有效位为 1 位;每行脏位数用 \(d\) 表示(通常回写取 1、全写取 0),全 Cache 的替换控制信息共 \(R\) 位,则在不计题设以外的校验与实现开销时:
替换信息可能按组保存,应按题设另算,不能默认每行都有固定数量的替换位。直接映射无需替换控制位,取 \(R=0\);若给定每组 \(r\) 位、共 \(S\) 组,则 \(R=Sr\)。题干只问数据区容量时,答案仍是 \(LB\) 字节。
5.3 替换和写策略¶
直接映射中,目标行唯一,无需选择替换对象;全相联或组相联中,目标范围已满时需使用替换算法,如 LRU(最近最久未使用)、FIFO(先进先出)和随机替换(Random)。与页面置换相同,LRU 命中时要更新最近使用次序,FIFO 命中时不改变装入次序。
写策略需分两种情况:写命中时如何更新下层存储器,以及写缺失时是否调入该块:
- 写命中时怎么写?
- 全写法(写直达 Write-Through):更新 Cache 时也向下层写入,可通过写缓冲暂存请求。通常无需脏位,但每次写都产生下层写流量;存在写缓冲时,还需区分请求已进入缓冲与主存实际完成更新。
- 回写法(写回 Write-Back):只修改 Cache,并将脏位(Dirty)置 1。替换该行时,脏行先写回,干净行可直接淘汰,从而减少下层写次数。
- 写缺失时调不调块?
- 写分配法(Write-Allocate):先把主存里那一块读进 Cache,再在 Cache 行里改写(常跟回写法搭档)。
- 非写分配法(Not-Write-Allocate):绕开 Cache 直接往主存里写,不把该块调进 Cache(常跟全写法搭档)。
5.4 访问序列分析¶
分析一串访存地址的命中情况时,可按以下步骤逐次更新 Cache 状态:
- 计算主存块号:\(\lfloor \text{地址}/\text{块大小} \rfloor\)。
- 计算目标行号或组号:\(\text{块号} \bmod S\),其中 \(S\) 为行数或组数,按题目映射方式确定。
- 检查目标项的有效位和标记,判断命中或缺失;若缺失,再按替换策略更新状态。
习题 9、13、15 可用于练习这套流程。
例如,初始为空的直接映射 Cache 有 4 行,每块 \(4\ \text{B}\)。依次访问字节地址 0, 1, 4, 0, 16, 0,主存块号为 0, 0, 1, 0, 4, 0,目标行号为 0, 0, 1, 0, 0, 0。前两次为缺失、命中;访问 4 缺失并装入 1 号行;再次访问 0 命中。访问 16 时,4 号块替换 0 号行中的 0 号块,因此最后访问 0 又缺失。共命中 2 次,命中率为 \(2/6 = 1/3\)。
C 语言二维数组按行优先(Row-major)连续存放。相邻的 a[i][j] 与 a[i][j+1] 在未跨块时可位于同一主存块,因此按行遍历通常有较好的空间局部性。按列访问,或多个数组反复映射到同一 Cache 行,都可能降低命中率。具体结果仍需按块大小、映射方式及访问顺序计算,见习题 11、12、13、15。
6 虚拟存储器(6,识记、领会、简单应用、综合应用)¶
虚拟存储器将按需调入的思想用于主存与辅存之间,由 MMU 和操作系统共同管理。软件策略见《操作系统概论》第 4 章,本章侧重地址转换硬件及其与 Cache 的衔接。
分页式虚拟存储将虚拟空间分为页、物理主存分为同样大小的页框,大小为 \(2^p\) 字节,例如 \(4\ \text{KB} = 2^{12}\ \text{B}\)。虚拟地址由虚页号 VPN和低 \(p\) 位的页内偏移 VPO组成,物理地址由页框号 PFN和同样的低 \(p\) 位页内偏移 PPO组成。页表记录映射及存在、保护、修改和使用等状态。确认页面驻留且访问合法后,将 PFN 与原偏移拼接,得到物理地址。
例:页大小 \(4\ \text{KB}\)(偏移占低 12 位,即 3 个十六进制位),20 位虚拟地址 12345H 拆出虚页号 VPN = 12H、页内偏移 345H;若查页表得知第 12H 号虚页的有效位为 1、对应物理页框号 PFN = ABH,拼出来的物理地址就是 AB345H。
快表(TLB)缓存近期页表项,减少访问主存页表的开销。下图按本节的物理地址查 Cache 模型,连接 TLB、页表、Cache、主存与磁盘的处理路径:
CPU 发出虚拟地址 (VPN | 页内偏移)
│
├─► 1. 查快表 TLB:命中?
│ ├── 是 ──────────────────────────────────────┐
│ └── 否(TLB 缺失)→ 2. 去主存查慢页表:有效位=1? │
│ ├── 是(页在主存)→ 填回 TLB ──────────┼─► 拼出物理地址 (PFN | 页内偏移)
│ └── 否(缺页异常!) │ │
│ └─► OS 调缺页异常处理程序: │ ▼
│ 从磁盘读入该页(满则置换)、 │ 3. 按物理地址切 (Tag | Index | Offset) 查 Cache:
│ 更新页表与 TLB,重跑本指令 │ ├── 命中 → 直接把数据送 CPU
└──────────────────────────────────────────────────┘ └── 缺失 → 从主存读入该数据块装入 Cache 行,再送 CPU
追踪这条路径时,注意三点:
- TLB 缺失 \(\ne\) 缺页(Page Fault):TLB 缺失只表示当前缓存没有映射,还需查询页表。页面若已驻留,补充 TLB 后即可继续;确认缺页后,才由操作系统处理,必要时启动磁盘 I/O。
- 先确认映射有效:在本节按物理地址查 Cache 的模型中,缺页表示当前虚页没有可用的驻留映射,必须先由操作系统处理,不能跳过地址转换直接宣布 Cache 命中。页面换出或映射失效时,系统还须使相关 TLB 项等状态保持一致;不要把 Cache 的包含关系与虚页是否驻留混为一谈。
- 两次切位使用不同的边界(见本章习题 17):先按页大小切出虚页号与页内偏移,查页表得到页框号,再拼出物理地址。随后按 Cache 块大小和组数,把物理地址重新切成
Tag + 组索引 + 块内偏移(直接映射时组索引就是行号)。两次切分的边界可能不同,不能沿用虚拟地址的分段。
7 考核要求¶
本章共 6 条考核条目:第 1、2、4 条要求领会,第 3 条包含简单应用,第 5 条 Cache 和第 6 条虚拟存储器均涵盖识记、领会、简单应用与综合应用。重点练习 DRAM 引脚和字位扩展(习题 3–5),Cache 地址切分、总位数与命中率(习题 8–15),以及页表与 Cache 联合地址追踪(习题 16–17)。
8 教材本章习题¶
题目取自教材第 5 章“习题”(共 17 题),答案取自教材附录“部分习题解答”(收录第 3、4、5、8、9、10、11、12、13、14、15、16、17 题;其余请对照教材自行完成)。
8.1 概念与简答¶
1. 给出以下概念的解释说明。
- 静态 RAM(SRAM)、动态 RAM(DRAM)、刷新、易失性存储器、相联存储器
- 存取时间、存储周期、存储器带宽、Flash 存储器、时间局部性
- 空间局部性、命中率、命中时间、缺失率、缺失损失
- 虚拟地址空间、虚拟地址、虚拟页号、物理地址、页框(页帧)
- 页表、页表基址寄存器、有效位(装入位)、修改位
- 缺页(page miss)、FIFO、LRU、快表(TLB)
答案与解析
教材附录未收本题解答,请对照教材自行完成。
2. 简单回答下列问题。
(1)计算机内部为何要采用层次化存储体系结构?层次化存储体系结构如何构成?
(2)SRAM 芯片和 DRAM 芯片各有哪些特点?各自用在哪些场合?
(3)CPU 和主存之间有哪两种通信定时方式?SDRAM 芯片采用什么方式和 CPU 交换信息?
(4)为什么在 CPU 和主存之间引入 cache 能提高 CPU 访存效率?
(5)为什么直接映射方式不需要考虑替换策略?
(6)为什么要考虑 cache 的一致性问题?读操作时是否要考虑 cache 的一致性问题?为什么?
(7)什么是物理地址?什么是逻辑地址?地址转换由硬件还是软件实现?为什么?
(8)什么是页表?什么是快表(TLB)?
(9)在存储器层次化结构中,“cache—主存”、“主存—磁盘”这两个层次有哪些不同?
答案与解析
教材附录未收本题解答,请对照教材自行完成。
8.2 存储器芯片与主存组织¶
3. 某计算机主存最大寻址空间为 4 GB,按字节编址,假定用 64 M×8 位的具有 8 个位平面的 DRAM 芯片组成容量为 512 MB、传输宽度为 64 位的内存条。要求回答下列问题。
(1)每个内存条需要多少个 DRAM 芯片?
(2)构建容量为 2 GB 的主存时,需要几个内存条?
(3)主存地址共有多少位?其中哪几位用作 DRAM 芯片内地址?哪几位为 DRAM 芯片内的行地址?哪几位为 DRAM 芯片内的列地址?哪几位用于表示芯片号?
答案与解析
参考答案: (1)512 MB / (64 M×8 位) = 8 片 DRAM。
(2)2 GB / 512 MB = 4 个内存条。
(3)最大寻址空间为 \(4\ \text{GB} = 2^{32}\ \text{B}\)、按字节编址,故主存地址共 32 位(\(A_{31}A_{30}\cdots A_{1}A_{0}\))。总线每次传输 64 位(8 字节),内存条上的 8 片 \(\times 8\) 位 DRAM 芯片采用低位交叉编址同时读写,因此最低 3 位 \(A_{2}A_{1}A_{0}\) 用作芯片号(选通 8 片中的哪一字节)。单根内存条容量 \(512\ \text{MB} = 2^{29}\ \text{B}\) 占低 29 位地址 \(A_{28}\cdots A_{0}\),扣掉低 3 位芯片号后,中间 26 位 \(A_{28}\cdots A_{3}\) 用作 DRAM 芯片内地址(对应单片 \(64\text{M} = 2^{26}\))。按行列对半划分,高 13 位 \(A_{28}\cdots A_{16}\) 为芯片内行地址,低 13 位 \(A_{15}\cdots A_{3}\) 为芯片内列地址。
4. 假定用 \(8 \text{K} \times 8\) 位的 EPROM 芯片组成 \(32 \text{K} \times 16\) 位的只读存储器,要求回答以下问题。
(1)数据寄存器最少应有多少位?
(2)地址寄存器最少应有多少位?
(3)共需多少个 EPROM 芯片?
答案与解析
参考答案: (1)数据寄存器最少应有 16 位。
(2)地址寄存器最少应有 15 位。
(3)共需 8 片 EPROM 芯片(\(32\text{K} \times 16\) 位 ÷ \(8\text{K} \times 8\) 位 = 8 片)。
5. 若一个 \(2^n \times b\) 位 DRAM 芯片的存储阵列是 \(r\) 行 \(\times c\) 列,则说明该芯片容量为 \(2^n \times b\) 位且 \(2^n = r \times c\),芯片内的地址位数为 \(n\),其中行地址位数为 \(\log_2 r\),列地址位数为 \(\log_2 c\),芯片中共有 \(b\) 个位平面,芯片的地址引脚数为 MAX(\(\log_2 r\), \(\log_2 c\)),数据引脚数为 \(b\)。\(n\) 位地址中高位部分为行地址,低位部分为列地址。为提高 DRAM 芯片的性价比,通常设置的 \(r\) 和 \(c\) 满足 \(r \leq c\) 且 \(|r - c|\) 最小。请说出以下几种 DRAM 芯片的地址引脚数和数据引脚数。
(1)256 K × 1 位
(2)16 M × 8 位
(3)32 M × 4 位
答案与解析
参考答案: (1)因为 \(256\ \text{K} = 2^{18} = 2^{9} \times 2^{9}\),存储矩阵为 512 行 \(\times\) 512 列,地址引脚数为 \(\log_{2}2^{9} = 9\),数据引脚数为 1。
(2)因为 \(16\ \text{M} = 2^{24} = 2^{12} \times 2^{12}\),存储矩阵为 4 096 行 \(\times\) 4 096 列,地址引脚数为 \(\log_{2}2^{12} = 12\),数据引脚数为 8。
(3)因为 \(32\ \text{M} = 2^{25} = 2^{12} \times 2^{13}\),存储矩阵为 4 096 行 \(\times\) 8 192 列,地址引脚数为 MAX\((\log_{2}2^{12}, \log_{2}2^{13}) = 13\),数据引脚数为 4。
6. 现代计算机中,SRAM 一般用于实现快速小容量的 cache,而 DRAM 用于实现慢速大容量的主存。以前超级计算机通常不提供 cache,而是用 SRAM 来实现主存(如 Cray 巨型机),请问:如果考虑成本,你还这样设计高性能计算机吗?为什么?
答案与解析
教材附录未收本题解答,请对照教材自行完成。
7. 对于数据的访问,分别给出具有下列要求的程序或程序段的示例:
(1)几乎没有时间局部性和空间局部性。
(2)有很好的时间局部性,但几乎没有空间局部性。
(4)空间局部性和时间局部性都好。
答案与解析
教材附录未收本题解答,请对照教材自行完成。
8.3 Cache 与程序局部性¶
8. 假定某计算机主存地址空间大小为 1 GB,按字节编址,cache 的数据区(即不包括标记、有效位等)有 64 KB,块大小为 128 字节,采用直接映射和直写(write through)方式。请问:
(1)主存地址如何划分?要求说明每个字段的含义、位数和在主存地址中的位置。
(2)cache 的总容量为多少位?
答案与解析
参考答案: (1)主存空间大小为 1 GB,按字节编址,说明主存地址为 30 位。cache 共有 64 KB/128 B = 512 行,因此,行索引(行号)为 9 位;块大小 128 字节,说明块内地址为 7 位。因此,30 位主存地址中,高 14 位为标志(Tag);中间 9 位为行索引;低 7 位为块内地址。
(2)因为采用直接映射,所以 cache 中无需替换控制位,直写方式下也无需修改(dirty)位,而标志位和有效位总是必须有的,所以,cache 总容量为 \(512 \times (128 \times 8 + 14 + 1) = 519.5\ \text{K}\) 位。
9. 假定某计算机的 cache 共 16 行,开始为空,块大小为 1 个字,采用直接映射方式,按字编址。CPU 执行某程序时,依次访问以下地址序列:2, 3, 11, 16, 21, 13, 64, 48, 19, 11, 3, 22, 4, 27, 6 和 11。要求:
(1)说明每次访问是命中还是缺失,试计算访问上述地址序列的命中率。
(2)若 cache 数据区容量不变,而块大小改为 4 个字,则上述地址序列的命中情况又如何?
答案与解析
参考答案: (1)cache 采用直接映射方式,其数据区容量为 16 行×1 字/行 = 16 字;主存被划分成 1 字/块,所以,主存块号 = 字号。因此,映射公式为
开始 cache 为空,以下是映射关系(字号-cache 行号)和命中情况。2-2: miss,3-3: miss,11-11: miss,16-0: miss,21-5: miss,13-13: miss,64-0: miss、replace,48-0: miss、replace,19-3: miss、replace,11-11: hit,3-3: miss、replace,22-6: miss,4-4: miss,27-11: miss、replace,6-6: miss、replace,11-11: miss、replace。
只有一次命中。
(2)cache 采用直接映射方式,数据区容量不变,还是 16 个字,每块大小为 4 个字,所以,cache 共有 4 行;主存被划分为 4 个字/块,所以,主存块号 = [字号/4]。以下是映射关系(字号-主存块号-cache 行号)和命中情况。2-0-0: miss,3-0-0: hit,11-2-2: miss,16-4-0: miss、replace,21-5-1: miss,13-3-3: miss,64-16-0: miss、replace,48-12-0: miss、replace,19-4-0: miss、replace,11-2-2: hit,3-0-0: miss、replace,22-5-1: hit,4-1-1: miss、replace,27-6-2: miss、replace,6-1-1: hit,11-2-2: miss、replace。命中 4 次。
块从 1 个字放大到 4 个字,同样 16 次访问,命中次数从 1 次升到 4 次。原因不在算法变聪明,而在每次缺失搬进来的东西变多了:紧随其后要用的相邻字已经躺在 cache 里,省掉了一趟主存。这正是空间局部性的实际收益。
但别把它读成「块越大越好」。块继续放大会让一行吃掉更多容量,能容纳的块数随之减少;工作集一旦变大,冲突缺失就会盖过这点好处。
10. 假定处理器时钟周期为 2 ns,某程序由 10 000 条指令组成,每条指令执行一次,其中的 40 条指令在取指令时,没有在 cache 中找到,其余指令都能在 cache 中取到。在执行指令过程中,该程序需要 8 000 次主存数据访问,其中,60 次没有在 cache 中找到。试问
(1)执行该程序得到的 cache 命中率是多少?
(2)若 cache 中存取一个信息的时间为 1 个时钟周期,缺失损失为 10 个时钟周期,则(CPU 的平均访存时间是多少?——教材复原件此处题干未印完,据答案补足问句)
答案与解析
参考答案: (1)cache 命中率为(1-40/10 000-60/8 000)×100% = 98.85%(注:此处为教材附录原式;若按总访问次数 \(10\,000 + 8\,000 = 18\,000\) 次、总缺失 \(40 + 60 = 100\) 次计算,综合命中率为 \(1 - 100 / 18\,000 \approx 99.44\%\))。
(2)CPU 的平均访存时间为 \(T_{c}+(1-p)\times T_{m}=1+(1-98.85\%)\times10=1+0.0115\times10=1.115\) 个时钟周期,相当于 \(1.115\times2\ \text{ns}=2.23\ \text{ns}\)。
11. 假定数组元素在主存按从左到右的下标顺序存放。试改变下列函数中循环的顺序,使得其数组元素的访问与排列顺序一致,并说明为什么修改后的程序比原来的程序执行时间短。
int sum_array (int a[N][N][N])
int i, j, k, sum = 0;
转写说明。 教材原程序为插图,此处仅存首行(函数头与变量声明),完整的循环嵌套见答案。
答案与解析
参考答案:
int sum_array (int a[N][N][N])
{
int i, j, k, sum = 0;
for (k = 0; k < N; k++)
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
sum += a[k][i][j];
}
修改后的程序,其数组元素的访问顺序与排列顺序一致,使得空间局部性比原程序好,数组元素访问时 cache 命中率更高,减少了访问主存的开销,故执行时间更短。
12. 分析比较以下三个函数中数组访问的空间局部性,并指出哪个最好,哪个最差?(三个函数见下)
#define N 1000
typedef struct { int vel[3]; int acc[3]; } point;
point p[N];
void clear1(point *p, int n)
{ int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < 3; j++) p[i].vel[j] = 0;
for (j = 0; j < 3; j++) p[i].acc[j] = 0;
}}
#define N 1000
typedef struct { int vel[3]; int acc[3]; } point;
point p[N];
void clear2(point *p, int n)
{ int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < 3; j++) p[i].vel[j] = 0;
for (j = 0; j < 3; j++) p[i].acc[j] = 0;
}}
#define N 1000
typedef struct { int vel[3]; int acc[3]; } point;
point p[N];
void clear3(point *p, int n)
{ int i, j;
for (j = 0; j < 3; j++) {
for (i = 0; i < n; i++) p[i].vel[j] = 0;
for (j = 0; j < 3; j++) p[i].acc[j] = 0;
}}
代码转写说明。 教材复原件中 clear1/clear2 正文重复、clear3 缺外层循环;按答案描述,clear2 应为 vel[j]/acc[j] 交替、clear3 应为 j 外层 i 内层(此三行为按答案反推,非教材原文)。
答案与解析
参考答案: 设 sizeof(int) = 4,则每个结构体元素 p[i] 占 \(6 \times 4 = 24\ \text{B}\),在内存中紧挨着铺成 vel[0] vel[1] vel[2] acc[0] acc[1] acc[2]。
| 结构体 | 元素内容(连续 24 B) |
|---|---|
p[0] |
vel[0] vel[1] vel[2] acc[0] acc[1] acc[2] |
p[1] |
vel[0] vel[1] vel[2] acc[0] acc[1] acc[2] |
| \(\vdots\) | \(\vdots\) |
三个函数的差别只在循环次序:clear1 是外层下标 i、内层 j 顺着 vel[j] 再 acc[j] 一路往下扫;clear2 是外层 i,内层让 vel[j] 与 acc[j] 交替访问;clear3 把 j 提到外层、i 放到内层,逐个字段把整个数组扫一遍。
clear1空间局部性最好:访问顺序与内存里的物理存放顺序完全一致(p[0]的 6 个字段写完才跳p[1]),每次按块调入 Cache 后整块能干完,块内其余字节全被顺次命中。clear2居中:在每个p[i]内部跳跃着访问,顺序是vel[0] → acc[0] → vel[1] → acc[1] → vel[2] → acc[2],相邻两次访问最大相差 12 B。若块大小小于 24 B,一个结构体要跨两块,访问每个p[i]至少缺失 2 次;若块大小超过 24 B,最好的情况也只缺失 1 次。clear3空间局部性最差:相邻两次访问跨越整个结构体,至少相差 24 B,等于每访问一个字段就要新调入一个块,若块大小小于 24 B 则命中率断崖式下跌。
结论:clear1 > clear2 > clear3。原因不在算法,而在访问模式与内存布局是否对齐。
13. 以下是对矩阵进行转置的程序段:
typedef int array[4][4];
void transpose(array dst, array src)
int i, j;
for (i = 0; i < 4; i++)
转写说明。 教材原程序为插图,此处仅存外层循环首行;按答案,循环体为
dst[j][i]=src[i][j]。
假设 \(\text{sizeof}(\text{int}) = 4\),且用来存放数据的 cache 中数据区大小为 32 B,采用直接映射、回写方式,块大小为 16 B,初始为空。数组 dst 从地址 0000C000H 开始存放,数组 src 从地址 0000C010H 开始存放。填写下表,说明对数组元素 src[row][col] 和 dst[row][col] 的访问是命中(hit)还是缺失(miss)。若 cache 的数据区大小改为 128 B 时,重新填写表中内容。
地址口径注。 教材复原件题面地址为 0000C010H,附录答案的行号分配只在 src 起址落在偶数块(如 0000C040H)时成立;按题面 C010H 复核,src 行号整体反相(1/0/1/0),且 src[0] 与 dst[1] 同块。考试按题面地址作答并说明差异。
答案与解析
参考答案: 因为块大小为 16 B,dst 和 src 起始地址的最后 4 位都是 0,因此都正好是在一个数据块的起始地址。从程序来看,数组访问过程如下:
src[0][0]、dst[0][0]、src[0][1]、dst[1][0]、src[0][2]、dst[2][0]、src[0][3]、dst[3][0]
src[1][0]、dst[0][1]、src[1][1]、dst[1][1]、src[1][2]、dst[2][1]、src[1][3]、dst[3][1]
src[2][0]、dst[0][2]、src[2][1]、dst[1][2]、src[2][2]、dst[2][2]、src[2][3]、dst[3][2]
src[3][0]、dst[0][3]、src[3][1]、dst[1][3]、src[3][2]、dst[2][3]、src[3][3]、dst[3][3]
每个数组元素有 4 个字节,所以 4 个数组元素占一个主存块,因此每次总是调入 4 个数组元素到 cache 的一行。
当数据区容量为 32 B 时,L1 data cache 中共有 2 行。数组元素 \(\text{dst}[0][i]\)、\(\text{dst}[2][i]\)、\(\text{src}[0][i]\)、\(\text{src}[2][i]\)(\(i=0\sim3\))都映射到 cache 第 0 行,数组元素 \(\text{dst}[1][i]\)、\(\text{dst}[3][i]\)、\(\text{src}[1][i]\)、\(\text{src}[3][i]\)(\(i=0\sim3\))都映射到 cache 第 1 行。因此,从上述访问过程来看,\(\text{src}[0][0]\) 所在的一个主存块(即存放 \(\text{src}[0][i]\)(\(i=0\sim3\))四个数组元素)刚调入 cache 后,\(\text{dst}[0][0]\) 所在主存块又把 \(\text{src}[0][0]\) 替换掉了。
| 32 B · src | col=0 | col=1 | col=2 | col=3 |
|---|---|---|---|---|
| row=0 | 0/miss | 0/miss | 0/hit | 0/miss |
| row=1 | 1/miss | 1/hit | 1/miss | 1/hit |
| row=2 | 0/miss | 0/miss | 0/hit | 0/miss |
| row=3 | 1/miss | 1/hit | 1/miss | 1/hit |
| 32 B · dst | col=0 | col=1 | col=2 | col=3 |
|---|---|---|---|---|
| row=0 | 0/miss | 0/miss | 0/miss | 0/miss |
| row=1 | 1/miss | 1/miss | 1/miss | 1/miss |
| row=2 | 0/miss | 0/miss | 0/miss | 0/miss |
| row=3 | 1/miss | 1/miss | 1/miss | 1/miss |
当数据区容量为 128 B 时,L1 data cache 中共有 8 行。数组元素 \(\text{dst}[0][i]\)、\(\text{dst}[1][i]\)、\(\text{dst}[2][i]\)、\(\text{dst}[3][i]\)、\(\text{src}[0][i]\)、\(\text{src}[1][i]\)、\(\text{src}[2][i]\)、\(\text{src}[3][i]\)(\(i=0\sim3\))分别映射到 cache 第 0、1、2、3、4、5、6、7 行。因此,不会发生数组元素的替换。每次总是第一个数组元素不命中,后面三个数组元素都命中。
| 128 B · src | col=0 | col=1 | col=2 | col=3 |
|---|---|---|---|---|
| row=0 | 4/miss | 4/hit | 4/hit | 4/hit |
| row=1 | 5/miss | 5/hit | 5/hit | 5/hit |
| row=2 | 6/miss | 6/hit | 6/hit | 6/hit |
| row=3 | 7/miss | 7/hit | 7/hit | 7/hit |
| 128 B · dst | col=0 | col=1 | col=2 | col=3 |
|---|---|---|---|---|
| row=0 | 0/miss | 0/hit | 0/hit | 0/hit |
| row=1 | 1/miss | 1/hit | 1/hit | 1/hit |
| row=2 | 2/miss | 2/hit | 2/hit | 2/hit |
| row=3 | 3/miss | 3/hit | 3/hit | 3/hit |
14. 已知 cache 1 采用直接映射方式,共 16 行,块大小为 1 个字,缺失损失为 8 个时钟周期;cache 2 也采用直接映射方式,共 4 行,块大小为 4 个字,缺失损失为 11 个时钟周期。假定开始时 cache 为空,采用字编址方式。要求找出一个访问地址序列,使得 cache 2 具有更低的缺失率,但总的缺失损失反而比 cache 1 大。
答案与解析
参考答案: 假设 cache1 和 cache2 的缺失次数分别为 x 和 y,根据题意,x 和 y 必须满足以下条件:\(11 \times y > 8 \times x\) 且 x > y,满足该条件的 x 和 y 有许多,例如,x=4, y=3;x=5, y=4 等。
对于以下的访问地址序列:0, 1, 4, 8,cache 1 缺失 4 次,而 cache 2 缺失 3 次;
对于以下的访问地址序列:0, 2, 4, 8, 12,cache 1 缺失 5 次,而 cache 2 缺失 4 次;
对于以下的访问地址序列:0, 3, 4, 8, 12, 16, 20,cache 1 缺失 7 次,而 cache 2 缺失 6 次;
如此等等,可以找出很多。
15. 某处理器带有一个数据区容量为 256 B 的 cache,其块大小为 32 B。以下 C 语言程序段运行在该处理器上,设 sizeof(int) = 4,编译器将变量 i, j, c, s 都分配在通用寄存器中,因此,只要考虑数组元素的访存情况。若 cache 采用直接映射方式,则当 s = 64 和 s = 63 时,缺失率分别为多少?若 cache 采用 2 路组相联映射方式,则当 s = 64 和 s = 63 时,缺失率又分别为多少?
int i, j, c, s, a[128];
……
for (i = 0; i < 10000; i++)
for (j = 0; j < 128; j = j + s)
c += a[j];
答案与解析
参考答案: 已知块大小为 32 B,占 8 个数组元素,cache 容量为 256 B = 8 行 \(\times\) 32 B/行,仅考虑数组访问情况。显然,\(a[0] \sim a[7]\) 在同一块;\(a[8] \sim a[15]\) 在同一块……以此类推。
(1)直接映射,s=64:访存顺序为 a[0]、a[64]、a[0]、a[64]、…,循环 10000 次。a[0]~a[63] 是前 8 块,a[64]~a[127] 是随后 8 块,两个块群各占满 8 个 cache 行。行号取块号对 8 取模,块号取元素下标除以每块元素数:
- a[0]:块号 \(\lfloor 0/8\rfloor=0\),行 \(0 \bmod 8=0\);
- a[64]:块号 \(\lfloor 64/8\rfloor=8\),行 \(8 \bmod 8=0\)。
两者同落第 0 行,后一次访问把前一次顶掉,每次数组访问都缺失,缺失率 100%。
(2)直接映射,s=63:访存顺序为 a[0]、a[63]、a[126]、a[0]、…,循环 10000 次。同样按块号取模:
- a[63]:块号 \(\lfloor 63/8\rfloor=7\),行 7;
- a[126]:块号 \(\lfloor 126/8\rfloor=15\),行 \(15 \bmod 8=7\)。
后两个元素同落第 7 行,每次互相冲突;a[0] 块号 0 落第 0 行,不受影响。每轮三次访问缺两次,缺失率约 67%。
(3)2 路组相联,s=64:8 行 2 路,共 4 组,组号取块号对 4 取模。
- a[0]:块号 0,组 \(0 \bmod 4=0\);
- a[64]:块号 8,组 \(8 \bmod 4=0\)。
两者同在第 0 组,可分别占该组的两个行位,不必互相顶掉,缺失率约为 0。
(4)2 路组相联,s=63:组号仍取块号对 4 取模。
- a[0]:块号 0,组 0;
- a[63]:块号 7,组 \(7 \bmod 4=3\);
- a[126]:块号 15,组 \(15 \bmod 4=3\)。
a[63] 与 a[126] 同组但可占两行,a[0] 独占组 0,三者互不冲掉,缺失率约为 0。
除数别写错。 块号要用「每块容纳的元素个数」去除,本题是 32 B ÷ 4 B = 8。若顺手用元素字节数 4 去除,\(\lfloor 63/4\rfloor\) 得 15,\(15 \bmod 8\) 仍是 7,与正确的 \(\lfloor 63/8\rfloor=7\) 同余——数字照样蒙对,式子全错,换个下标立刻露馅。四种情形的结论与教材一致,但过程必须按块号算。
8.4 虚拟存储器¶
16. 假定一个虚拟存储系统的虚拟地址为 40 位,物理地址为 36 位,页大小为 16 KB。若页表中有有效位、存储保护位、修改位(脏位)、使用位,共占 4 位,磁盘地址不记录在页表中,则该存储系统中每个进程的页表大小为多少?如果按计算出来的实际大小构建页表,则会出现什么问题?
答案与解析
参考答案: 每页大小有 16 KB,所以虚拟页数为 \(2^{40}\) B/16 KB= \(2^{40-14}=2^{26}\)。
物理页面和虚拟页面大小相等,所以物理页号的位数为 36-14=22。
页表项位数为有效位+保护位+脏位+使用位+物理页号位数=4+22=26 位。
为简化页表访问,每项大小取 32 位。因此,每个进程的页表大小为 \(2^{26}\times32\ \text{b}=256\ \text{MB}\)。
如果按实际计算出的页表大小构建页表,则页表过大而导致页表无法一次装入。
17. 某计算机存储器按字节编址,虚拟(逻辑)地址空间大小为 16 MB,主存(物理)地址空间大小为 1 MB,页面大小为 4 KB;cache 采用直接映射方式,共 8 行;主存与 cache 之间交换的块大小为 32 B。系统运行到某一时刻时,页表的部分内容和 cache 的部分内容分别如下图所示,图中页框号及标记字段的内容为十六进制形式。
展开查看页表与 Cache 表
| 虚页号 | 有效位 | 页框号 | | --- | --- | --- | | 0 | 1 | 06 | | 1 | 1 | 04 | | 2 | 1 | 15 | | 3 | 1 | 02 | | 4 | 0 | - | | 5 | 1 | 2B | | 6 | 0 | - | | 7 | 1 | 32 | *表 (a) 页表的部分内容(教材图 (a) 转写)* | 行号 | 有效位 | 标记 | | --- | --- | --- | | 0 | 1 | 020 | | 1 | 0 | - | | 2 | 1 | 01D | | 3 | 1 | 105 | | 4 | 1 | 064 | | 5 | 1 | 14D | | 6 | 0 | - | | 7 | 1 | 27A | *表 (b) cache 的部分内容(教材图 (b) 转写)*请回答下列问题。
(1)虚拟地址有几位,哪几位表示虚页号?物理地址有几位,哪几位表示页框号(物理页号)?
(2)使用物理地址访问 cache 时,物理地址应划分成哪几个字段?要求说明每个字段的位数及在物理地址中的位置。
(3)虚拟地址 001C60H 所在的页面是否在主存中?若在主存中,则该虚拟地址对应的物理地址是什么?访问该地址时是否 cache 命中?要求说明理由。
答案与解析
参考答案: (1)虚拟地址空间 \(16\ \text{MB} = 2^{24}\ \text{B}\),按字节编址,故虚拟地址共 24 位;页大小为 \(4\ \text{KB} = 2^{12}\ \text{B}\),页内偏移占低 12 位,故高 12 位为虚页号。物理地址空间 \(1\ \text{MB} = 2^{20}\ \text{B}\),故物理地址共 20 位,同样低 12 位为页内偏移,故高 8 位为页框号(物理页号)。
(2)Cache 采用直接映射、共 8 行,行索引占 \(\log_2 8 = 3\) 位;块大小 \(32\ \text{B} = 2^5\ \text{B}\),块内地址占 5 位。物理地址共 20 位,扣掉行索引 3 位和块内地址 5 位,剩 12 位为标志(Tag)。故 20 位物理地址自高到低切分为:高 12 位标志(\(A_{19} \sim A_{8}\))+中间 3 位 Cache 行索引(\(A_{7} \sim A_{5}\))+低 5 位块内地址(\(A_{4} \sim A_{0}\))。
(3)\(001\text{C}60\text{H} = 0000\ 0000\ 0001\ 1100\ 0110\ 0000\text{B}\),24 位中高 12 位即虚页号 \(0000\ 0000\ 0001\text{B} = 001\text{H}\)。查页表,001H 号虚页的有效位为 1,说明该页已在主存中,页框号为 \(04\text{H} = 0000\ 0100\text{B}\)。
拼出物理地址:高 8 位填页框号 0000 0100,低 12 位仍取原页内偏移 1100 0110 0000,合起来是 0000 0100 1100 0110 0000B,即 04C60H。
按(2)的切分:Tag = 高 12 位 0000 0100 1100B = \(04\text{C}\text{H}\);行索引 = 中间 3 位 011B = 3;块内地址 = 低 5 位 00000B。查 Cache 第 3 行,有效位为 1、标记为 \(105\text{H}\),但 \(105\text{H} \ne 04\text{C}\text{H}\),标记不匹配,故不命中(该块此前未装入 Cache 第 3 行)。
9 自编客观题(补充)¶
以下 15 题按 2024 年 10 月、2025 年 4 月两卷的客观题考点自编,用于检索式回忆;不是教材原题。
9.1 单项选择题¶
1. 计算机采用层次化存储体系结构,主要依据是
答案与解析
参考答案: B。层次化靠上层保存下层近期可能使用的内容,前提是局部性;主频、容量与位宽都不是分层的理由。
2. 用 8K×8 位芯片组成 32K×16 位存储器,所需芯片数与字地址位数分别是
答案与解析
参考答案: D。片数为 \((32\text{K}/8\text{K})\times(16/8)=8\);32K 个字需 15 位字地址,位数与数据宽度无关。
3. 某主存按字节编址、有 16 根地址线,其最大容量是
答案与解析
参考答案: C。16 位地址可编 \(2^{16}=65\ 536\) 个字节单元,即 64 KB;按字编址才要另乘字长。
4. 直接映射 Cache 共 8 行,主存块号 13 应装入
答案与解析
参考答案: A。行号 = 块号 mod 行数 = \(13 \bmod 8 = 5\);拿块号直接当行号是常见错法。
5. 关于 SRAM 与 DRAM,下列说法正确的是
答案与解析
参考答案: C。SRAM 用双稳态电路、DRAM 用电容电荷,只有 DRAM 需要刷新;两者都是易失性存储器。
6. Cache 采用写回法,替换某一行前必须写回主存的条件是
答案与解析
参考答案: A。只有脏行与主存不一致才需回写;有效位只说明该行内容是否可用。
7. 页面大小为 4 KB,虚拟地址 00002345H 的页内偏移是
答案与解析
参考答案: C。4 KB 页给 12 位偏移,即最低 3 个十六进制位 345H;高位 00002H 是虚页号(值为 2)。
8. TLB 命中但数据 Cache 缺失时,下列判断正确的是
答案与解析
参考答案: D。TLB 命中只说明映射在,数据块可能不在 Cache;是否缺页要看页表项有效位。
9. Cache 数据区 16 KB、块大小 32 B、采用 4 路组相联,则共有多少组
答案与解析
参考答案: B。行数 \(16\ \text{KB}/32\ \text{B}=512\),组数 \(512/4=128\);忘记除以路数就会误选 512。
10. 命中率 98%、命中时间 1 ns、缺失损失 50 ns(不含命中时间)时,平均访问时间是多少
答案与解析
参考答案: C。\(1+0.02\times50=2\) ns;把命中时间与完整缺失时间再相加就重复计算了。
9.2 填空题¶
11. 存储周期是连续两次独立操作允许的最小间隔,其中可能包含 ___ 时间。
答案与解析
参考答案: 恢复
12. Cache 与主存之间按 ___ 交换数据,一个主存块装入 Cache 的一行。
答案与解析
参考答案: 块
13. 按字节编址、地址为 32 位的主存,最大容量是 ___ GB。
答案与解析
参考答案: 4
14. 虚拟地址转物理地址时,页内偏移 ___ 保留,只用页框号替换虚页号。
答案与解析
参考答案: 原样
15. 一个 2 路组相联 Cache 共 8 行,则共有 ___ 组。
答案与解析
参考答案: 4
10 闭卷复习与跨章联系(补充)¶
一、闭卷自答(合上书逐题口述)
- 存储器按访问方式分哪几类?随机存取为什么不等于随机选地址?
- SRAM 与 DRAM 各靠什么存信息?DRAM 为什么必须刷新,刷新等于 CPU 重写全部数据吗?
- 位扩展、字扩展、字位扩展各扩展什么?给目标容量怎样算芯片数、引脚数与地址划分?
- 三种映射的地址字段怎样切?给容量、块大小、路数能否算出标记、索引、偏移?
- 命中率与平均访问时间怎样算?写命中策略与写缺失策略分别解决什么问题,教材中常见哪些组合?
- 页表、TLB、Cache 各存什么?串行查询模型下一次访存的顺序如何,缺页由谁处理?
二、本章易错
- “随机存取(RAM/ROM)”指的是访问任意单元耗时相同、与物理位置无关,别按字面误解成“随机挑一个地址访问”(第 1 节)。
- 算 Cache 总容量(总位数)时,不能只算数据区字节数,必须把每行的有效位、标记位、回写法脏位和替换控制位一并加进去(第 5.2 节)。
- 本章的物理地址查 Cache 模型需要两次划分:先按页大小拆分虚拟地址,经 TLB 或页表取得页框号并组成物理地址;再按 Cache 块大小和组数划分
Tag + 行/组索引 + 块内偏移。字段边界未对齐四位时,不能直接截取十六进制字符(第 5.2、6 节)。
三、本章骨架
| 层次 | 上层器件 | 下层器件 | 交换单位 | 缺失由谁处理 |
|---|---|---|---|---|
| 寄存器—Cache | 寄存器 | SRAM | 字 | 编译器与硬件 |
| Cache—主存 | SRAM | DRAM | 块(行) | 硬件 |
| 主存—辅存 | DRAM | 磁盘与 SSD | 页 | 操作系统 |
四、跨章指路
- 本章与流水线(见第 4 章)的接口是 MEM 段:Cache 命中与否直接决定一条指令的访存代价,进而影响 CPI。
- 与互连及输入输出(见第 6 章)的接口是 I/O 与 DMA 对主存的占用,两者共享同一套存储带宽。
- 虚拟存储与操作系统课程的内存管理是同一机制的不同视角,见《操作系统概论》第 4 章的内存管理。