Appearance
题目
计算机 M 字长为 32 位,按字节编址,数据 cache 的数据区大小为 32KB,采 8 路组相联,主存块大小为 64B,cache 命中时间为 2 个时钟周期,缺失损失为 200 个时钟周期,采用页式虚拟存储,页大小为 4KB。数组 d 的起始地址为 0180 0020H(VA31~VA0)。
(1) 主存地址中的 Cache 组号,块内地址分别占几位?VA 中哪些位可以作为 Cache 索引。
(2) d[100] 的 VA 是多少?d[100] 所在主存块中对应的 Cache 组号是多少?
(3) 设代码已经在 cache 中,i,x 已装入内存,但不在 cache,则 d[0] 在其主存块内的偏移量是多少?执行 for 的过程中,访问 d 的 Cache 缺失率和数组元素的平均访问时间分别是多少?(缺失率用百分比表示,保留两位小数)
(4) d 分布在几个页中?若代码已在主存,d 不在主存,则执行 for 的过程中,访问 d 所引起的缺页次数是
c
int x, d[2048], i;
for (i = 0; i < 2048; i++)
d[i] = d[i]/x;解析
本题考查 8 路组相联 Cache 在 数组遍历 + 起始地址不对齐 这种情境下的缺失分析,以及结合页式存储的缺页判定。
关键点:
- 首元素不在主存块边界:导致首末两块都"半装",使总块数比理想多 1;
d[i] = d[i] / x双访问:每个数组元素被访问 2 次(一次读取、一次写入),算缺失率时分母要乘 2;- 数组首址不在页起点:跨页数 = ceil((起始偏移 + 总长) / 页大小)。
(1) Cache 字段位数 + VA 中的 Cache 索引位 [3 分]
块内偏移: Cache 块 64B → 位(占 VA[5:0])。
Cache 组数:
Cache 组号: 位(占 VA[11:6])。
Cache 索引位: 由块内偏移 + 组号共同决定地址映射到哪一组的哪一字节,VA 的低 12 位(即 [11:0])整体可作为 Cache 索引。换言之,VA[11:6] 就是组号字段。
易错点: "Cache 索引位"和 "Cache 组号位"是同一概念的不同说法——组号 6 位用来选哪一组。本题 VA 低 12 位与页内偏移重合(页大小 4KB),意味着可以 不查页表就直接用虚拟地址索引 Cache——这是 VIPT(虚拟索引、物理标签)设计的根本。
(2) d[100] 的 VA + Cache 组号 [3 分]
Step 1. 算 d[100] 的虚拟地址。
数组首地址 0180 0020H,每元素 4B:
Step 2. 算 Cache 组号。
0180 01B0H 二进制:
按 [Tag … | 组号 6 位 | 偏移 6 位] 切:
- 块内偏移([5:0])=
110000B= 48; - 组号([11:6])=
000110B= 6。
(3) d[0] 块内偏移 + 缺失率 + 平均访问时间 [4 分]
Step 1. d[0] 在主存块中的偏移。
0180 0020H 的低 6 位 = 100000B = 32。即 d[0] 位于其所在 64B 主存块的 第 32 字节 处(块的中间)。
Step 2. 算数组占用的 Cache 块数。
数组总大小 = ;理想块数 = 块。
但首元素在偏移 32 处 → 第 1 个块只装下 d[0..7](32B),最后一块也只用一半 → 实际占用 129 块:
| 块 | 装的元素 | 字节范围 |
|---|---|---|
| 第 1 块(半块) | d[0..7](8 个) | 0180 0020H ~ 0180 0040H |
| 第 2 ~ 128 块(满块) | d[8..2039](每块 16 个) | 中段 |
| 第 129 块(半块) | d[2040..2047](8 个) | 末段 |
Step 3. 算缺失率。
每个块的第一次访问 miss,之后命中。每个 d[i] 被访问 2 次(读 + 写,即 d[i] = d[i]/x 的左 / 右两侧):
- 总访问次数 = ;
- 总 miss 数 = 129(每块首次 miss)。
易错点: "d[i] 访问 2 次"这件事一定要算上——题干
d[i] = d[i]/x在汇编层面是 lw + sw 两条指令。漏算会得到 6.30% 的错误答案。
Step 4. 算平均访问时间。
按"miss 用 200 个周期、hit 用 2 个周期"(两者互斥,不叠加):
(4) 数组分布的页数 + 缺页次数 [3 分]
页数计算。 页大小 4KB = 4096B;数组总长 8192B;首址在 0180 0020H(页 01800H,页内偏移 32)。
数组覆盖范围:
| 页号 | 页地址区间 | 数组占用 |
|---|---|---|
01800H | 0180 0000H ~ 0180 0FFFH | 偏移 32 起的 4064 字节 |
01801H | 0180 1000H ~ 0180 1FFFH | 全 4096 字节 |
01802H | 0180 2000H ~ 0180 2FFFH | 起首 32 字节 |
数组占用 4064 + 4096 + 32 = 8192 = 8KB ✓。
缺页次数: 题目说"d 不在主存",所以每个含数组数据的页首次访问都触发缺页:
易错点: 8KB 数组在没有偏移的情况下确实只跨 2 页,但本题首址不在页边界 → 多跨一页。这就是为什么"对齐"对存储系统性能这么重要。