Appearance
题目
假设对于题 44 中的计算机 M 和程序段 P 的机器代码,M 采用页式虚拟存储管理;P 开始执行时,(R1)=(R2)=0,(R6)=1000,其机器代码已调入主存但不在 Cache 中;数组 A 未调入主存,且所有数组元素在同一页,并存储在磁盘同一个扇区。请回答下列问题并说明理由。
(1) P 执行结束时,R2 的内容是多少?
(2) M 的指令 Cache 和数据 Cache 分离。若指令 Cache 共有 16 行,Cache 和主存交换的块大小为 32 字节,则其数据区的容量是多少?若仅考虑程序段 P 的执行,则指令 Cache 的命中率为多少?
(3) P 在执行过程中,哪条指令的执行可能发生溢出异常?哪条指令的执行可能产生缺页异常?对于数组 A 的访问,需要读磁盘和 TLB 至少各多少次?
解析
本题在 2014-44 的程序段 P 之上叠加 指令 Cache 命中率、溢出异常 / 缺页异常的指令归属、TLB 与磁盘访问次数 的分析。
核心两条线:
- 指令 Cache —— 6 条指令(24B)落在同一主存块(32B),所以整个循环只缺一次;
- 数据访问 —— 数组 A 在同一页同一磁盘扇区,第一次访问 A[0] 触发缺页 → 一次磁盘读把整页搬入主存;之后 A[1..999] 都在内存里。
(1) P 执行结束时 R2 的内容 [1 分]
循环条件 i < N(N = 1000)。R2 装 i,每轮自增 1。当 R2 自增到 1000 时不再满足条件,跳出循环:
(2) 指令 Cache 数据区容量与命中率 [3 分]
数据区容量。
命中率分析。
P 共 6 条指令 = (一块大小),起始地址 08048100H 是 32 的倍数(100H = 256 整除 32),所以 P 整体落在 同一个主存块 内。
- 第 1 次取指(I1)miss → 把整块(含 P 全部 6 条)装入 Cache;
- 之后无论是本轮 I2~I6 还是后续 999 轮的 I1~I6,全在 Cache 中 → 全部命中。
总指令访问次数:。Miss 次数:1。
易错点: 不要把"循环 1000 次"理解成"重新装载 1000 次"。Cache 命中后的循环仅在 Cache 内取指,主存块不再被替换(只要没冲突)。
(3) 溢出异常、缺页异常、磁盘 / TLB 访问次数 [8 分]
(3.1) 哪条指令可能溢出异常?
只有 指令 4 (add R1, R1, R5) 可能溢出——它是 sum += A[i] 的累加,当 A[i] 较大时累计的 sum 可能越出 int 范围。
其他指令为何不会溢出:
- 指令 1
sll R4, R2, 2:R2 ≤ 1000,左移 2 位最大 4000,远小于 ; - 指令 2
add R4, R4, R3:算的是数组元素地址,正常程序里在地址空间内; - 指令 5
add R2, R2, 1:i 最大 1000,不溢出。
(3.2) 哪条指令可能产生缺页异常?
指令 3 (load R5, 0(R4)) —— 这是唯一的访存指令,访问 A[i]。其他指令都不访存(程序代码已在主存且不缺页)。
(3.3) 数组 A 的读磁盘次数。
数组 A 全部元素 在同一页 + 同一磁盘扇区:
- 第一次访问 A[0] → TLB miss → 查页表 → 页不在主存 → 缺页异常 → 1 次磁盘读(把整页调入主存);
- 之后 A[1..999] 都在主存的同一页里 → 不再缺页 → 不再读磁盘。
(3.4) TLB 访问次数。
每次访问数组元素都要查 TLB(地址翻译走的就是 TLB → 缺则查页表)。基本次数 = 1000。
但 A[0] 被访问 2 次:
- 第一次:查 TLB → miss → 触发缺页 → 处理后;
- 缺页处理完毕后,CPU 重新执行 load 指令 → 再查一次 TLB → 这次命中。
编者注(生僻术语): "缺页处理后重新执行 load" 是大多数 ISA 的"精确异常"语义——异常返回的 PC 指向引发异常的那条指令本身,因此 load 会被重做一次。这就解释了为什么 A[0] 的 TLB 查找会算 2 次。若只查页表 1 次(即把 TLB 缺失合并不算访问 TLB),答案会是 1000;408 评分接受 1001 / 1002 两种。
【评分说明】
① 第 1 问中若答案除指令 4 外还包含其他运算类指令(1、2、5),给 1 分;其他情况 0 分。 ② 第 2 问只要回答"load 指令"即可得分。 ③ 第 3 问若答案给出 TLB 次数为 1002 也给分;若直接给出正确次数但未说明原因,给 3 分;若数字错但思路正确,酌情给分。