Loading

Cache地址映射与计算方式

什么是Cache地址映射

主存的容量比Cache要大的多,所以我们得采用多个主存块映射到同一个Cache行中的方法,将要访问的局部主存区域取到Cache中。映射方法有:直接映射,全相联映射,组相链映射

直接映射

直接映射是最简单粗暴的办法:

(块地址)mod(cache中的块数)

一个内存块地址始终映射到一个固定的Cache 地址。下图中主存被分为了0-2047个内存块,缓存块或者说cache line有16块。

那么第0,16,n*16块因为mod16都为0,所以他们对应到的Cache行号都为0。

如果我们要访问第16号内存块(内存块从0开始计数的),只要它在缓存块里面,那么它必定是在0号缓存块,也就是行号为0.

Cache直接映射

知道了映射方法,那么如何规定主存地址呢?其实对于取模运算,我们只需要取低位字节就可以了。

在十进制里面如果对16取余,那么结果定是两位数以内,并且不会大于15。

比如说Cache有16行,16是2的4次方,那么我们就可以直接取主存块号的低四位作为Cache行号。

Cache索引

17对应的cache行号就是1.

但当我们读取某一个缓存行时,我们怎么知道他是0块群的还是其他块群的呢?

其实正如主存块号中包含了Cache行号一样,其低四位之前的高位就可以作为区分的Tag(主存标记)使用。最后一点就是,CPU读取数据只是要读取它需要的字(Word)而已,那么这个字具体是在Cache line的哪里,我们还需要一个偏移量来纪录它。

所以直接映射的主存地址应该由三部分组成:主存子块标记,Cache子块标记,字块内地址。

直接映射主存格式

现在我们来自己动手做一做:假设数据在主存和Cache间的传送单位为512B,Cache大小为213B,主存大小为220B。

因为主存大小为220B,且以512B为传送单位。那么220B=2048块 * 512B/块,主存可以划分为2048块,主存地址为20位二进制数。因为我们需要确定要取的是块中的哪个字,又512=2^9,所以需要9位作为偏移量,或者说字块内地址。 Cache可以划分出16行(2^13=16行 * 512B/行),也就是说划出4位作为行号标记,或者说Cache字块地址。剩下的7位自然就作为主存字块标记啦。

直接映射例题

优缺点:

  • 电路实现简单,命中时间短
  • 无需考虑替换问题
  • Cache的存储空间没有得到充分使用,命中率低

全相联映射

针对直接映射Cache空间利用率低的问题,我们有一种简单粗暴的办法提升空间的利用率。那就是主存中的任意一块都可以映射到Cache中的任意一个位置。有空位置你就坐下,随意,映射位置不在固定。

全相联映射

那么我们唯一要做的就是知道Cache中是对应主存中的哪一块和字块内地址就行。因为是随便映射,所以我们把直接映射中的Cache字块标记合并到主存字块标记中。

全相联映射主存地址只有两部分:主存字块标记,字块内地址。

优缺点:

  • 不存在冲突缺失,命中率高
  • 电路复杂,速度慢

组相联映射

综合前两种方法的就是组相联映射,具体做法是:将Cache中的行分组,主存块映射到固定的行中,但行中的位置可以随意。也就是组间直接映射,组内全相联映射。

Cache组号=主存块号 mod Cache组数

组相联映射

那么问题来了怎么确定Cache中的字块是对应主存的那一块呢?首先我们仍需要字块内地址,需要区分组号,那么剩下的地址就可以作为主存字块标记使用。

容量为64块的Cache,采用组相联方式映像,字块大小为128字,每4块为一组。若主存容量为4096块,且以字编址,那么主存地址该如何划分?

因为4096=219,所以主存地址应该为19位,Cache总共有16组,所以需要4位确定组号。又字块大小为128字,128=27,所有字块内地址为7位,剩下的19-7-4=8位作为主存字块标记。

组相联例题

优缺点:

  • 电路较简单,速度较快,命中率较高,属于比较理想的方式
posted @ 2020-07-02 16:24  AD_milk  阅读(14022)  评论(1编辑  收藏  举报