52

我正在学习系统架构课程,但我无法理解直接映射缓存的工作原理。

我看过几个地方,他们以不同的方式解释它,这让我更加困惑。

我无法理解的是什么是标签和索引,它们是如何选择的?

我讲座的解释是:“地址分为两部分索引(例如15位),用于直接寻址(32k)RAM的其余地址,存储标签并与传入标签进行比较。”

那个标签是从哪里来的?它不能是 RAM 中内存位置的完整地址,因为它使直接映射缓存无用(与完全关联缓存相比)。

非常感谢。

4

4 回答 4

100

好的。所以我们先来了解一下CPU是如何与缓存交互的。

内存有三层(广义上​​)—— cache(一般由SRAM芯片制成)、main memory(一般由DRAM芯片制成)和storage(一般是磁性的,像硬盘一样)。每当 CPU 需要来自某个特定位置的任何数据时,它首先会搜索缓存以查看它是否存在。缓存在内存层次结构上最接近 CPU,因此它的访问时间最短(成本最高),因此如果 CPU 正在寻找的数据可以在那里找到,则构成“命中”,并且数据从那里获得供 CPU 使用。如果不存在,则必须将数据从主内存移动到缓存,然后才能被 CPU 访问(CPU 通常只与缓存交互),这会导致时间损失。

因此,为了找出缓存中是否存在数据,应用了各种算法。一种是这种直接映射缓存方法。为简单起见,我们假设一个内存系统有 10 个可用的高速缓存内存位置(编号为 0 到 9)和 40 个可用的主内存位置(编号为 0 到 39)。这张图总结了一下:

在此处输入图像描述

有 40 个可用的主内存位置,但缓存中最多只能容纳 10 个。所以现在,通过某种方式,来自 CPU 的传入请求需要重定向到缓存位置。这有两个问题:

  1. 如何重定向?具体来说,如何以一种不会随着时间而改变的可预测方式来做到这一点?

  2. 如果缓存位置已经被一些数据填满,来自 CPU 的传入请求必须识别它需要数据的地址是否与数据存储在该位置的地址相同。

在我们的简单示例中,我们可以通过简单的逻辑进行重定向。假设我们必须将 40 个从 0 到 39 顺序编号的主内存位置映射到 10 个编号为 0 到 9 的缓存位置,一个内存位置的缓存位置n可以是n%10. 所以 21 对应于 1, 37 对应于 7,依此类推。这就变成了index

但是 37, 17, 7 都对应 7。所以为了区分它们,就来了tag。所以就像 index 是n%10, tag 是int(n/10)。所以现在 37、17、7 将有相同的索引 7,但不同的标签如 3、1、0 等。也就是说,映射可以完全由标签和索引这两个数据指定。

所以现在如果请求地址位置 29,那将转换为标签 2 和索引 9。索引对应于缓存位置编号,因此缓存位置编号。将查询 9 以查看它是否包含任何数据,如果是,则关联的标签是否为 2。如果是,则 CPU 命中,将立即从该位置获取数据。如果它是空的,或者标签不是2,这意味着它包含与其他一些内存地址对应的数据,而不是29(虽然它会有相同的索引,这意味着它包含来自9、19这样的地址的数据, 39 等)。所以这是一个 CPU 未命中,并且来自位置号的数据。主存中的 29 必须加载到位置 9 的缓存中(并且标签更改为 2,并删除之前存在的所有数据),之后它将被 CPU 获取。

于 2015-12-01T18:33:48.787 回答
12

让我们举个例子。一个 64 KB 的高速缓存,具有 16 字节的高速缓存行,有 4096 个不同的高速缓存行。

您需要将地址分解为三个不同的部分。

  1. 最低位用于在您取回缓存行时告诉您缓存行中的字节,这部分不直接用于缓存查找。(本例中的位 0-3)
  2. 下一位用于索引缓存。如果您将缓存视为一大列缓存行,则索引位会告诉您需要在哪一行中查找数据。(本例中的位 4-15)
  3. 所有其他位都是 TAG 位。这些位存储在您存储在缓存中的数据的标签存储中,我们将缓存请求的相应位与我们存储的数据进行比较,以确定我们正在缓存的数据是否是正在请求的数据。

您用于索引的位数是 log_base_2(number_of_cache_lines) [确实是集合的数量,但在直接映射缓存中,行数和集合的数量相同]

于 2013-04-11T16:30:44.287 回答
2

直接映射缓存就像一个表,它具有也称为缓存行的行和至少 2 列,一列用于数据,另一列用于标记。

它是这样工作的:对缓存的读取访问将地址的中间部分称为索引并将其用作行号。同时查找数据和标签。接下来,需要将该标记与地址的上半部分进行比较,以确定该行是否来自内存中的同一地址范围并且有效。同时,地址的低部分可以用来从缓存行中选择请求的数据(我假设一个缓存行可以保存几个字的数据)。

我强调了一点数据访问和标签访问+比较同时发生,因为这是减少延迟的关键(缓存的目的)。数据路径 ram 访问不需要是两个步骤。

优点是读取基本上是简单的表查找和比较。

但它是直接映射的,这意味着对于每个读取地址,缓存中只有一个位置可以缓存该数据。所以缺点是很多其他地址会被映射到同一个地方,可能会竞争这个缓存行。

于 2013-04-12T22:00:22.513 回答
1

我在图书馆找到了一本好书,它为我提供了我需要的清晰解释,现在我将在这里分享它,以防其他学生在搜索缓存时偶然发现这个线程。

这本书是 Hennesy 和 Patterson 所著的“计算机体系结构 - 一种定量方法”第 3 版,第 390 页。

首先,请记住,主内存被划分为缓存块。如果我们有一个 64 字节的缓存和 1 GB 的 RAM,那么 RAM 将被划分为 128 KB 的块(1 GB 的 RAM / 64B 的缓存 = 128 KB 块大小)。

从书中:

块可以放在缓存中的什么位置?

  • 如果每个块在缓存中只能出现一个位置,则称缓存为直接映射的。使用以下公式计算目标块:<RAM Block Address> MOD <Number of Blocks in the Cache>

所以,假设我们有 32 块 RAM 和 8 块缓存。

如果我们要将 RAM 中的第 12 块存储到缓存中,RAM 块 12 将存储到缓存块 4 中。为什么?因为 12 / 8 = 1 余数 4。余数是目标块。

  • 如果一个块可以放置在缓存中的任何位置,则称该缓存是完全关联的。

  • 如果一个块可以放置在缓存中一组受限制的位置中的任何位置,则缓存设置为关联

基本上,集合是缓存中的一组块。一个块首先映射到一个集合上,然后该块可以放置在集合内的任何位置。

公式为:<RAM Block Address> MOD <Number of Sets in the Cache>

因此,假设我们有 32 块 RAM 和一个缓存,分为 4 组(每组有两个块,意味着总共 8 个块)。这样设置 0 将具有块 0 和 1,设置 1 将具有块 2 和 3,依此类推...

如果我们要将 RAM 块 12 存储到缓存中,RAM 块将存储在缓存块 0 或 1 中。为什么?因为 12 / 4 = 3 余数为 0。因此选择了集合 0,并且可以将块放置在集合 0 内的任何位置(表示块 0 和 1)。

现在我将回到我原来的地址问题。

如果块在缓存中,如何找到它?

缓存中的每个块帧都​​有一个地址。为了清楚起见,一个块既有地址又有数据。

块地址分为多个部分:Tag、Index 和 Offset。

标签用于在缓存中查找块,索引仅显示块所在的集合(使其非常冗余),偏移量用于选择数据。

“选择数据”是指在一个缓存块中显然会有多个内存位置,偏移量用于在它们之间进行选择。

所以,如果你想想象一个表,这些将是列:

TAG | INDEX | OFFSET | DATA 1 | DATA 2 | ... | DATA N

标记将用于查找块,索引将显示块在哪个集合中,偏移量将选择其右侧的字段之一。

我希望我对此的理解是正确的,如果不是,请告诉我。

于 2013-04-23T02:15:15.057 回答