【问题标题】:Concept of "block size" in a cache缓存中“块大小”的概念
【发布时间】:2011-11-12 22:13:05
【问题描述】:

我刚刚开始学习直接映射和设置关联缓存的概念。 我有一些非常基本的疑问。来了。

假设地址是 32 位长,我有一个 32KB 的缓存,64Byte 的块大小和 512 帧,“块”中实际存储了多少数据?如果我有一条从内存位置的值加载的指令,并且该值是 16 位整数,那么 64 字节块之一现在是否仅存储 16 位(2 字节)整数值。块中的其他 62 个字节呢?如果我现在有另一个加载指令,它也加载一个 16 位整数值,这个值现在根据加载地址进入另一个帧的另一个块(如果地址映射到前一条指令的同一帧,那么前一个值被逐出并且该块再次仅在 64 个字节中存储 2 个字节)。正确的?

如果这似乎是一个非常愚蠢的疑问,请原谅我,这只是我想正确理解我的概念。

【问题讨论】:

    标签: operating-system cpu-cache


    【解决方案1】:

    我为某人打了这封电子邮件来解释缓存,但我认为您可能会发现它也很有用。

    您有可以引用 RAM 中字节的 32 位地址。 您希望能够缓存您访问的数据,以便以后使用。

    假设您想要一个 1-MiB(220 字节)的缓存。

    你是做什么的?

    您需要满足 2 个限制:

    1. 所有地址的缓存应尽可能统一。即您不想偏向任何特定类型的地址。
      • 你是怎么做到的?使用余数!使用 mod,您可以将 any 整数均匀分布在您想要的任何范围内。
    2. 您想帮助尽量减少簿记成本。这意味着例如如果您在 1 个字节的块中进行缓存,您不想存储 4 个字节的数据只是为了跟踪 1 个字节的所属位置。
      • 你是怎么做到的?您存储的块大于 1 个字节。

    假设您选择 16 字节(24-byte)块。这意味着您可以缓存 220 / 24 = 216 = 65,536 个数据块。

    您现在有几个选择:

    • 您可以设计缓存,以便任何内存块中的数据都可以存储在任何个缓存块中。这称为全关联缓存。
    • 好处是它是“最公平”的缓存类型:所有块都被完全平等地对待。
    • 权衡是速度:要找到放置内存块的位置,您必须搜索 每个 缓存块以获得可用空间。这真的很慢。
    • 您可以设计缓存,使来自任何内存块的数据仅存储在单个缓存块中。这称为直接映射缓存。
    • 好处是它是最快的缓存类型:您只需要检查项目是否在缓存中。
    • 折衷方案是,现在,如果您碰巧有一个错误的内存访问模式,您可以让 2 个块连续地相互踢出,而未使用的块仍保留在缓存中。
    • 您可以混合使用这两种方法:将单个内存块映射到多个块。这就是真正的处理器所做的——它们有 N 路组关联缓存。

    直接映射缓存:

    现在您有 65,536 个数据块,每个数据块有 16 个字节。
    您将其作为 65,536 个“行”存储在缓存中,每个“行”由数据本身以及元数据(关于块所属的位置、是否有效、是否已写入等)组成。

    问题: 内存中的每个块如何映射到缓存中的每个块?

    回答: 好吧,您正在使用直接映射缓存,使用 mod。这意味着地址 0 到 15 将映射到缓存中的块 0; 16-31 被映射到第 2 块,等等......当你到达 1-MiB 标记时它会环绕。

    那么,给定内存地址 M,你如何找到行号 N?简单:N = M % 220 / 24。
    但这只会告诉您在哪里存储数据,而不是如何检索它。一旦你存储了它,并尝试再次访问它,你必须知道哪个这里存储了 1-MB 的内存部分,对吗?

    这就是元数据的一部分:标签位。如果它在第 N 行,那么您只需要知道在 mod 操作期间 quotient 是什么。其中,对于 32 位地址,大 12 位(因为余数是 20 位)。

    所以你的标签变成了 12 位长——具体来说,是任何内存地址的最上层 12 位。
    而且您已经知道,最低 4 位用于偏移在一个块(因为内存是字节寻址的,一个块是 16 个字节)。
    这为内存地址的“索引”位留下了 16 位,可用于查找该地址所属的 行。 (这只是一个除法+余数运算,但是是二进制的。)

    您还需要其他位:例如您需要知道一个块实际上是否有效,因为当 CPU 开启时,它包含无效数据。所以你添加了 1 位元数据:有效位。

    您将了解其他一些内容,用于优化、同步等......但这些是基本的。 :)

    【讨论】:

    • 块大还是小块哪个效率更高?
    • @Faizan:这取决于很多因素,包括您的内存带宽。较小的块大小以更高的成本 ($) 为您提供更精细的粒度(更好),并且可能从 RAM 中获得更少的吞吐量。没有一个答案。
    • @Mehrdad 当您说要发现将映射内存块的缓存块时,您会说这是 M(内存地址) mod S(缓存大小),但这样地址 0 将被映射到块 0,地址 1 将映射到块 1,等等。此外,在您的示例中,缓存中会有 2^20 个块,这是错误的。还是我错过了什么?
    • @nj2237:是的,听起来你明白了。
    • @ryanwebjackson:These slides 可能有帮助吗?不过很难说,我个人不知道任何来源(我只是用谷歌搜索找到这个)。如果你愿意,欢迎你继续问我问题,我不介意。
    【解决方案2】:

    我假设您了解标记、索引和偏移量的基础知识,但这里有一个简短的解释,正如我在计算机体系结构课上学到的。块被替换为 64 字节块,因此每次将新块放入缓存时,它都会替换所有 64 字节,无论您是否只需要一个字节。这就是为什么在寻址缓存时会有一个偏移量来指定您想要从块中获取的字节。以您的示例为例,如果仅加载 16 位整数,则缓存将按索引搜索块,检查标签以确保其数据正确,然后根据偏移量获取字节。现在,如果您加载另一个 16 位值,假设使用相同的索引但不同的标签,它将用新块替换 64 字节块并从指定的偏移量获取信息。 (假设直接映射)

    我希望这会有所帮助!如果您需要更多信息或者这仍然是模糊的,请告诉我,我知道有几个很好的网站可以很好地教授这个。

    【讨论】:

    • 是的,它有帮助.. 但请给我其他网站以及额外的阅读.. 无论如何谢谢
    • @hektor 看看这个link,它对记忆和不同的替换技术非常有用,也是对我帮助最大的一种。它甚至还有交互式 java 模块。
    猜你喜欢
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2011-07-08
    • 2017-04-11
    • 1970-01-01
    • 2014-05-10
    相关资源
    最近更新 更多