2009年第14题
14、某计算机的 Cache 共有 16 块,采用 2 路组相联映射方式(即每组 2 块)。每个主存块大小为 32B,按字节编址。主存 129 号单元所在主存块应装入到的 Cache 组号是( )
A. 0 \qquad B. 1 \qquad C. 4 \qquad D. 6
解析
根据题目内容,可知本题所涉及到的知识点包括:
-
Cache 映射方式:指主存地址与 Cache 地址之间的映射规则,即确定主存中的数据块如何放置到 Cache 中的特定位置。其核心目的是解决主存与 Cache 之间的地址转换问题,以提高数据访问效率。根据映射规则的不同,主要分为“直接映射”“全相联映射”“组相联映射”三种方式。
-
直接映射:即一对一固定映射,主存中的每个块只能映射到 Cache 中唯一的一个特定块。
-
地址结构分解(按字节编址):
-
块内地址(Offset):由主存块大小决定,如块大小为 32B,则 Offset 占 5 位( log 2 32 = 5 \log_2 32 = 5 log232=5)。
-
Cache 块号(Index):由 Cache 总块数决定,如 Cache 有 16 块,则 Index 占 4 位( log 2 16 = 4 \log_2 16 = 4 log216=4)。
-
标记(Tag):剩余高位地址,用于区分映射到同一 Cache 块的不同主存块。
-
计算公式: Cache块号 = 主存块号 m o d Cache总块数 \text{Cache块号} = \text{主存块号} \mod \text{Cache总块数} Cache块号=主存块号modCache总块数
-
-
-
全相联映射(Fully Associative Mapping):即任意映射,主存中的每个块可以映射到 Cache 的任意一块。
-
地址结构分解:
-
块内地址(Offset):与直接映射相同,由主存块大小决定。
- 标记(Tag):包含主存块号的全部高位地址,用于在 Cache 中全相联查找(比较所有 Cache 块的标记)。
-
-
特点:无需 Index 字段,直接通过标记匹配。
-
-
组相联映射(Set Associative Mapping):即分组映射,Cache 被划分为若干组(Set),每组包含若干块(路数,Way)。主存块只能映射到 Cache 中对应组的任意一块(组间直接映射,组内全相联映射)。
-
地址结构分解:
- 块内地址(Offset):同前,由主存块大小决定。
- 组号(Index):由 Cache 的组数决定,如 Cache 有 16 块、2 路组相联(每组 2 块),则组数 = 8,Index 占 3 位 log 2 8 = 3 \log_28=3 log28=3 。
- 标记(Tag):剩余高位地址,用于在组内通过全相联比较确定具体块。
-
计算公式: Cache组号 = 主存块号 mod Cache组数 \text{Cache组号}=\text{主存块号}~\text{mod}~\text{Cache组数} Cache组号=主存块号 mod Cache组数 (组数 = Cache 总块数 / 路数)
-
-
按字节编址:指内存地址以字节为单位进行编号。例如,在本题中,主存 129 号单元指的是从 0 开始计数的第 129 个字节。
三种映射方式比较如下:
特性** | 直接映射 | 全相联映射 | 组相联映射 |
---|---|---|---|
映射规则 | 固定唯一块 | 任意块 | 固定组内任意块 |
地址结构 | 标记 + Index+Offset | 标记 + Offset | 标记 + Index+Offset |
冲突率 | 高 | 低 | 中(随路数增加降低) |
硬件复杂度 | 低 | 高 | 中 |
典型应用 | 早期 CPU Cache | 小容量高速缓存 | 现代 CPU Cache(如 L1/L2) |
本题中已知 Cache 共16块,采用 2 路组相联映射,因此:
组数
=
Cache块数
/
路数
=
16
/
2
=
8
组(组号
0
∼
7
)
组数 = \text{Cache块数} / 路数 = 16 / 2 = 8~组(组号~0\sim 7)
组数=Cache块数/路数=16/2=8 组(组号 0∼7)
路数=2,即每组包含 2 块。
计算本题所要求的主存块应装入到的 Cache 组号有如下两种方法。
方法 1
本题中主存按字节编址,根据前述组相联映射知识可知,如果主存地址表示成二进制,其结构应为:
主存地址
=
标记
⏟
高位
组号
⏟
中间
块内地址
⏟
低位
主存地址=\underbrace{标记}_{高位}\quad\underbrace{组号}_{中间}\quad\underbrace{块内地址}_{低位}
主存地址=高位
标记中间
组号低位
块内地址
主存地址 129,转换为二进制是 10000001
。
- 块内地址(Offset):块大小为 32B,则
log
2
(
32
)
=
5
\log_2(32) = 5
log2(32)=5 位,即主存地址的最低 5 位
00001
为 Offset。 - 组号(Index):Cache 共 16 块,2 路组相联,则组数 = 16/2 = 8,组号位数为
log
2
(
8
)
=
3
\log_2(8) = 3
log2(8)=3 位,主存地址中 Offset 以上的连续 3 位为 Index,即
100
,对应的十进制是 4。 - 标记(Tag):剩余的高位地址。本题总地址为 8 位,Offset 占 5 位、Index 占 3 位,无剩余高位,故 Tag 为空(实际应用中 Tag 位数由主存容量决定)。
故:Cache 组号是 4。
方法 2
先计算主存块号,而后计算组号。
- 按字节编制,主存 129 单元即为从 0 开始的第 129 个字节,所以主存块号还可以用下面的方法计算:
主存块号 = ⌊ 主存地址 / 主存块大小 ⌋ = ⌊ 129 / 32 ⌋ = 4 主存块号=\lfloor主存地址/主存块大小\rfloor=\lfloor129/32\rfloor=4 主存块号=⌊主存地址/主存块大小⌋=⌊129/32⌋=4
注意:主存块号,从 0 开始。
- 组相联映射中,组号 = 主存块号 mod 组数。本题中组数为 8,因此组号 = 4 % 8 = 4 4 \% 8 = 4 4%8=4。
本题答案:C
以上两种方法的等价性说明
主存地址由 “块号” 和 “块内偏移” 组成: 主存地址 = 主存块号 × 块大小 + 块内偏移 ( 块内地址 ) 主存地址=主存块号\times块大小+块内偏移(块内地址) 主存地址=主存块号×块大小+块内偏移(块内地址) 。
例如:块大小为 32B(5 位偏移),主存地址 129 对应的主存块号为 ⌊ 129 / 32 ⌋ = 4 \lfloor 129 / 32 \rfloor = 4 ⌊129/32⌋=4 ,偏移为 129 % 32 = 1 129 \% 32 = 1 129%32=1。
组数通常设计为 2 的幂次(如 2 m 2^m 2m),以便利用二进制位运算快速计算组号。
设:主存块号为 ( B ),二进制表示为 b n b n − 1 … b m b m − 1 … b 0 b_n b_{n-1} \dots b_m b_{m-1} \dots b_0 bnbn−1…bmbm−1…b0,组数为 G = 2 m G = 2^m G=2m,则 B m o d G = B & ( G − 1 ) B \mod G = B \& (G-1) BmodG=B&(G−1)(按位与运算),即取低 m m m 位。这低 m m m 位正是 Cache 组号的二进制值。因此,组号 = 主存块号 mod 组数 本质是通过二进制低位提取实现分组映射。
主存地址分解法和主存块号模运算法等价的关键是:主存块号是主存地址去掉偏移量后的部分,主存地址的 “Index 位” 必然等于主存块号的 “低 ( m ) 位”。例如:
-
主存地址 129(二进制 10000001),块大小 32B(Offset 5 位:00001),
-
主存块号 4(二进制 100),其低 3 位(100)即组号,与主存地址中间 3 位(100)一致。
所以,组号计算的本质:
KaTeX parse error: Can't use function '$' in math mode at position 149: …_{\text{二进制分解}}$̲
通过主存块号的低位二进制位(或等价的模运算),将主存块映射到固定组,确保 “组内灵活放置,组间唯一对应”。