Cache 的映射方式

2022年9月18日 1966点热度 2人点赞 0条评论
内容纲要

首先映射是按照块来映射的,每个块内都有一个块内地址,记录每个字长的位置。

本文部分图片来源参考:https://blog.csdn.net/weixin_42649617/article/details/105092395

直接映射

特点是内存与 Cache 之间的映射位置是固定的,其中内存到 Cache 的映射位置计算是取余。
file

每个内存块的的大小跟 Cache 的块大小一致,内存块数量为 M, Cache 块数量为 N。

一个内存块的序号是 M(i),那么在 Cache 中的位置是 M(i)%N = N(i)

例如 Cache 块数量是 100 个,内存块数量是 1000 个,那么在内存位置 666 中的块,在 Cache 的位置是 666 % 100 = 66

要注意,直接映射是根据 Cache 大小决定的,每次映射 100 个。 就块上面的 666 块号,需要一次性映射 600-699 序号的 100 个块到 Cache 中。每次将一个范围的块映射到 Cache 中。

file

虽然已经映射,但是 CPU 查找的时候是需要通过一些地址格式从 Cache 和 内存中查找的,需要一个表记录 Cache 和 内存地址。

求解题目需要知道:

  • Cache 地址格式:[Cache 块地址,块内地址];
  • 内存地址格式:[主存标记,Cache 块号,块内地址];

例题:主存 1MB,Cache 16KB,块大小 512 字节。
块大小 512 字节,即 2^9 个字节,需要使用 9 位长度记录每个字节的位置。
Cache 需要记录每个块的位置,则 16KB/512字节 = 32 = 2^5 ,需要 5 位长度记录块号,块表的容量就是 2^5

则 Cache 地址需要 5+9=14 位,因此:

file

下标从 0 开始。

但是内存不是这样计算的,不能用1MB/512字节 = 2048 = 2^11,获得 11 这个数字。

因为内存是一次性按照 Cache 大小划分的,内存每次映射 16KB 到 Cache 中,一旦发现没有命中,需要一次性替换 16KB,即 32 个块。

因此,主存标记是 1MB/16KB = 2^6,需要 6 位标记当前内存哪个范围的块映射到了 Cache。
所以, CPU 要表示主存的地址,需要 [6,5,9] 个长度,即 20 位。

问,主存地址为 CDE8FH 的单元,在 Cache 的什么地方。

CDE8FH 即16进制 CDE8F ,转二进制 为 1100 1101 1110 1000 1111,刚刚好为 20 位。
6 位是主存标记,这里用不到,去掉之后变成 01 1110 1000 1111
5 位是块号,即 01 111 ,即 15。
9 位是块内号,即 0 1000 1111 即 143。

所以, CDE8F,在 Cache 的 01111 块,内内地址是 01001111

全相联映射

file

首先不管内存到 Cache 是怎么映射的,当 CPU 要查找一个内存时,首先在 目录表(下面会说到) 中查找,要逐个遍历,判断内存是否已经映射到 Cache,最坏的情况是遍历整个 Cahce。

设内存块数为 M,Cache 块数为 N,那么就有 M*N 种映射情况。

为了记录这种映射关系,需要一个目录表记录 映射关系。

file

全相联映射适合 Cache 容量小的情况,否则这个目录表会很大。

Cache 地址的计算跟直接映射的一致。

内存地址只有两个参数:[主存标记,块内]。先根据块定位,然后直接找到块内地址。

例题:主存 1MB,Cache 16KB,块大小 512 字节。

Cache 地址长度:[5,9];一共 14 位。

内存标记,是给每个块做标记,因此 1MB/512字节=2^11 ,内存块标记需要 11 位。

所以内存地址长度:[11,9]。

问,主存地址为 CDE8FH 的单元,在 Cache 的什么地方。

CDE8FH 即16进制 CDE8F ,转二进制 为 1100 1101 1110 1000 1111

块号是:1100 1101 111

块内号是:0 1000 111

组相联映射

先将多个相连的块划分为一个组,按照直接映射的方式映射到 Cache,然后组内的块,按照全相联的方式自由映射。

内存地址长度:[内存标识,Cache 组号,块内地址]。

内存分组并不是相连的。

file

如果 Cache 每组有 N(5) 个块,主存有 M(100) 个块,则主存分组 :M/N = n(20),

那么,第一个组的序号 j 是 0,

所以一个组的块组成是 (0,20,40,60,80),组内的序号按照 0-4 标识,即组内号。

例题:主存 1MB,Cache 16KB,块大小 512 字节,在 16 路组相联的情况下,求内存地址格式。

主存标识:1MB/16/512 = 2^7

组地址:16=2^4

块内地址:512 = 2^9

所以内存地址长度是 [7,4,9]。

题目实例

file

(1)直接映射

主存标识:2MB/16KB=2^7

块地址:16KB/32=2^9

块内地址:8*32/8 = 32 = 2^5,但是因为题目要求是字块,也就是还要分一层,

所以 8 个字块:2^3,需要 3 个长度,32 位,即 4 个字节 2^2,需要 2 个长度。

所以,内存地址:[7,9,3,2]。

file

(2)全相联映射

每个块 32 字节,则主存标记:2MB/32=2^16

file

(3)组相联映射

内存标记:2MB/16/32 = 2^12

组内标记:16=2^4

内存地址:[12,4,3,2]

而原作者的答案应该错了:

file

痴者工良

高级程序员劝退师

文章评论