【复习408】Cache主存地址映射

Cache主存地址映射

CPU访问内存时使用的是主存物理地址,但数据可能存放在Cache中。因此,需要一个机制能快速判断所需数据是否在Cache中(即“命中”,Hit),如果在,则需要将其从Cache中取出。这个将主存地址转换为Cache地址并进行查找的过程,就是地址映射。其核心任务是解决一个问题:一个主存块(Block)可以存放到Cache中的哪个或哪些位置。

1. 映射的基本原理与地址结构

为了实现快速查找,主存地址通常被逻辑上划分为几个部分。对于一个容量为 2M2^M2M 字节、按字节编址的主存和一个容量为 2C2^C2C 字节、块大小(或称行大小)为 2B2^B2B 字节的Cache,主存地址(M位)的通用结构如下:

高位部分 (标记)中间部分 (索引)低位部分 (块内偏移)
TagIndexBlock Offset
  • 块内偏移 (Block Offset) : 用于确定所访问的数据在特定缓存块内的具体位置。其位数为。例如,如果块大小为64字节(B),则块内偏移需要6位 。

  • 索引 (Index) : 用于确定主存块应该映射到Cache的哪一行(直接映射)或哪一组(组相联映射)。其位数取决于映射方式和Cache的组织结构 。

  • 标记 (Tag) : 用于区分映射到同一个Cache行/组的不同主存块。当CPU提供的地址通过索引找到Cache中的某个位置后,需要将地址中的标记部分与该位置存储的标记进行比较,若一致且有效位为1,则判定为命中。

下面,详细讨论三种主要的映射方式。

2. 直接映射 (Direct Mapping)

直接映射是最简单的映射方式。它规定主存中的每一个块只能映射到Cache中的一个唯一固定的行 。这个映射关系通常由一个简单的模运算确定:

Cache行号 = 主存块号 mod Cache总行数

  • 地址结构: 在直接映射中,主存地址被划分为三个部分: 标记(Tag) 、 行索引(Index) 和 块内偏移(Offset)
  +------------------+----------------+----------------+
  |      Tag         |     Index      |  Block Offset  |
  +------------------+----------------+----------------+
  • 工作原理:
    1. CPU发出一个主存地址。
    2. 根据地址中的Index部分,直接定位到Cache的唯一 一行。
    3. 比较该行存储的Tag与CPU地址中的Tag部分。
    4. 如果Tag匹配且该行有效,则Cache命中。根据Block Offset从该行中取出数据。
    5. 如果Tag不匹配或该行无效,则Cache未命中(Miss)。此时需要从主存中读取包含该地址的整个块,将其存入由Index指定的Cache行,并更新该行的Tag和有效位。

优点: 实现简单,硬件开销小,查找速度快,因为不需要复杂的比较电路,只需根据索引直接定位。

缺点: 冲突率高。即使Cache有大量空闲空间,如果两个频繁访问的主存块恰好需要映射到同一个Cache行,它们会不断地相互替换,导致“颠簸”(Thrashing)现象,严重降低Cache命中率 。

3. 全相联映射 (Fully Associative Mapping)

全相联映射提供了最大的灵活性。它允许主存中的任意一个块可以被放置到Cache中的任意一个行。

  • 地址结构: 在这种方式下,由于没有固定的映射位置,所以不需要Index字段。主存地址被划分为两部分: 标记(Tag)块内偏移(Offset)
  +----------------------------------+----------------+
  |               Tag                |  Block Offset  |
  +----------------------------------+----------------+
  • 工作原理:
    1. CPU发出一个主存地址。
    2. 将地址中的Tag部分与Cache中所有行的Tag同时进行比较。
    3. 如果任意一行的Tag匹配且有效,则Cache命中。根据Block Offset从该行中取出数据。
    4. 如果所有行都不匹配,则Cache未命中。此时需要启动替换策略选择一个牺牲行,从主存中读取新块替换之,并更新该行的Tag。

优点: 映射方式灵活,空间利用率最高,冲突率最低,因为只要Cache有空闲位置就能装入新块 。

缺点: 硬件实现极为复杂且昂贵。需要为Cache的每一行都配备一个比较器来并行比较Tag,这导致成本高、功耗大,并且随着Cache容量增大,比较逻辑的规模会急剧增长 。因此,纯粹的全相联映射通常只用于小容量的缓存,如TLB(Translation Lookaside Buffer)。

4. 组相联映射 (Set-Associative Mapping)

组相联映射是直接映射和全相联映射的一种折中方案,旨在平衡成本与性能 。它将Cache的行分成若干个组(Set),组与组之间采用直接映射,而每个组内部则采用全相联映射

Cache组号 = 主存块号 mod Cache总组数
如果一个组内包含k个行,就称为k路组相联(k-way set-associative)。

  +------------------+----------------+----------------+
  |      Tag         |   Set Index    |  Block Offset  |
  +------------------+----------------+----------------+

  • 工作原理:
    1. CPU发出一个主存地址。
    2. 根据地址中的Set Index部分,直接定位到Cache的唯一一个组。
    3. 将地址中的Tag部分与该组内所有k个行的Tag同时进行比较。
    4. 如果组内任意一行的Tag匹配且有效,则Cache命中。根据Block Offset从该行中取出数据。
    5. 如果组内所有行都不匹配,则Cache未命中。启动替换策略,从该组的k个行中选择一个牺牲行,从主存读取新块替换之,并更新该行的Tag。

优点: 通过在组内提供有限的灵活性,显著降低了冲突率(相比直接映射),同时硬件成本和复杂度远低于全相联映射(只需k个比较器)。

缺点: 相较于直接映射,实现略复杂,查找时间稍长;相较于全相联映射,仍然存在组间冲突的可能。

5. 综合计算示例与地址划分图

让我们通过一个具体的例子来固化理解。
假设条件:

  • 主存地址空间:32位
  • Cache容量:64 KB
  • Cache块大小:64 B
  • 映射方式:4路组相联 (4-way set-associative)

计算过程:

1. 计算块内偏移 (Offset) 位数:

  • 块大小为 64 B = 262^626 B。
  • 因此,Offset需要 6 位来寻址块内的每一个字节 。
  • 地址范围:[0:5]

2. 计算组数和组索引 (Set Index) 位数:

  • Cache总行数 = Cache容量 / 块大小 = 64 KB / 64 B = (64 * 1024) B / 64 B = 1024 行。
  • Cache组数 = Cache总行数 / 路数 = 1024 / 4 = 256 组 。
  • Set Index需要 log256log256log256 即8位来唯一标识每一个组 。(这里的log256log256log256是以2为底的,打不出来那个2,尴尬😢)
  • 地址范围:[6:13]

3. 计算标记 (Tag) 位数:

  • Tag位数 = 总地址位数 - Set Index位数 - Offset位数。
  • Tag位数 = 32 - 8 - 6 = 18 位。
  • 地址范围:[14:31]

地址划分图 (4路组相联):

       31                14 13              6 5               0
      +--------------------+----------------+----------------+
      |      Tag (18)    | Set Index (8)| Offset (6)   |
      +--------------------+----------------+----------------+
      <-- 用于和组内各行Tag比较 --> <-- 定位到256个组之一 --> <-- 在64B块内寻址 -->

对比其他映射方式下的地址划分:

  • 如果采用直接映射:
    • 总行数 = 1024 行。Index需要log1024log1024log1024 即10位。(这里的log同样是以2为底的)
    • Offset仍然是6位。
    • Tag = 32 - 10 - 6 = 16位。
   31                16 15              6 5               0
  +--------------------+----------------+----------------+
  |      Tag (16)    |   Index (10) | Offset (6)   |
  +--------------------+----------------+----------------+

  • 如果采用全相联映射:

    • 没有Index或Set Index。
    • Offset仍然是6位。
    • Tag = 32 - 6 = 26位。
   31                                  6 5               0
  +------------------------------------+----------------+
  |               Tag (26)           | Offset (6)   |
  +------------------------------------+----------------+

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L.EscaRC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值