我刚刚开始学习直接映射和设置关联缓存的概念。 我有一些非常基本的疑虑。到此为止。
假设地址是32位长,并且我有一个32KB缓存,64Byte块大小和512帧,实际存储了多少数据"块"?如果我有一个从存储器位置加载一个值的指令,并且该值是16位整数,那么64Byte块之一现在只存储一个16位(2Bytes)整数值。块中的其他62个字节是什么?如果我现在有另一个加载指令也加载一个16位整数值,这个值现在进入另一个帧的另一个块,具体取决于加载地址(如果地址映射到前一个指令的同一帧,则先前的值被驱逐并且块再次以64字节存储仅2字节)。正确?
请原谅我,如果这似乎是一个非常愚蠢的怀疑,它只是我想要正确地得到我的概念。
答案 0 :(得分:26)
我输入此电子邮件给某人解释缓存,但我认为您可能会发现它也很有用。
你有32位地址可以引用RAM中的字节。 您希望能够缓存您访问的数据,以便以后使用它们。
假设您需要1-MiB(2 20 字节)缓存。
你做什么?
您需要满足2个限制:
- 在所有地址中,缓存应尽可能统一。即你不想偏向任何特定类型的地址。
- 你是怎么做到的?使用剩余!使用mod,您可以在任何您想要的范围内均匀分配任何整数。
- 您希望帮助最小化簿记费用。这意味着例如如果你以1字节为单位进行缓存,则不希望存储4个字节的数据只是为了跟踪1个字节所属的位置。
醇>
- 你是怎么做到的?存储大于1个字节的块。
假设您选择16字节(2 4 - 字节)块。这意味着您可以缓存2 20 / 2 4 = 2 16 = 65,536个数据块。
您现在有几个选择:
- 您可以设计缓存,以便来自任何内存块的数据可以存储在任何缓存块中。这将被称为完全关联缓存。
- 好处是它是“最公平”的缓存:所有块都被完全平等对待。
- 权衡是速度:要找到放置内存块的位置,您必须在每个缓存块中搜索可用空间。这真的很慢。
- 您可以设计缓存,以便来自任何内存块的数据只能 存储在单个缓存块中。这将被称为直接映射缓存。
- 好处是它是最快的缓存类型:您只需检查项目是否在缓存中。
- 权衡的是,现在,如果你碰巧有一个糟糕的内存访问模式,你可以有2个块连续相互踢,而未使用的块仍然留在缓存中。
- 您可以混合使用两者:将单个内存块映射到多个块。这就是真正的处理器所做的 - 它们具有N路组关联缓存。
直接映射缓存:
现在你有65,536个数据块,每个块有16个字节 您将其存储为缓存中的65,536“行”,每个“行”包含数据本身,以及元数据(关于块所在的位置,是否有效,是否已写入等)。
问题: 内存中的每个块如何映射到缓存中的每个块?
答案: 好吧,你正在使用直接映射缓存,使用mod。这意味着地址0到15将被映射到缓存中的块0; 16-31被映射到块2等等...当它到达1-MiB标记时它会环绕。
所以,给定内存地址M,你如何找到行号N?容易:N = M%2 20 / 2 4 但这只会告诉您存储数据的位置,而不是检索的方式。一旦你存储它,并尝试再次访问它,你必须知道这里存储了 1 MB的内存部分,对吗?
这是一个元数据:标记位。如果它在第N行,那么在mod操作期间你需要知道的是商是什么。对于32位地址,其中12位大(因为余数是20位)。
因此,您的标记变为12位长 - 特别是最高 12位的任何内存地址。
并且您已经知道最低的4位用于块内的偏移(因为存储器是字节寻址的,而块是16字节)。
这为存储器地址的“索引”位留下了16位,可用于查找地址所属的行。 (它只是一个除法+余数运算,但是是二进制运算。)您还需要其他位:例如您需要知道块是否实际上有效,因为当CPU打开时,它包含无效数据。因此,您添加1位元数据:有效位。
您将了解其他位,用于优化,同步等......但这些是基本的。 :)
答案 1 :(得分:5)
我假设你知道标签,索引和偏移的基础知识,但这是我在计算机体系结构课程中学到的简短解释。块被替换为64字节块,因此每次将新块放入高速缓存时,无论是否只需要一个字节,它都会替换所有64个字节。这就是为什么在寻址缓存时有一个偏移量,它指定了你想从块中获取的字节。举个例子,如果只加载16位整数,缓存将通过索引搜索块,检查标记以确保其正确的数据,然后根据偏移量获取字节。现在,如果你加载另一个16位值,假设使用相同的索引但不同的标记,它将用新块替换64字节块并从指定的偏移量获取信息。 (假设直接映射)
我希望这有帮助!如果你需要更多的信息或者这仍然是模糊的让我知道,我知道几个很好的网站,做得很好。