Cache和主存的映射方式

        阅读本文前,请确保自己已经了解了Cache的作用,以及Cache和主存为何需要地址映射。不然可能会懵。

先提出几个问题,看能不能准确回答,看完文章之后能不能呢?

1.行、块、组分别是什么?

2.Cache的位数由什么组成?

3.主存中的位数由什么组成?

4.直接映射时CPU的访存过程?

行、块、组的定义

行:是cache内的一个容器,存储块以及其他信息(例如有效位和标记位)

块:块是一个固定大小的信息包,是cache和主存之间交换数据的最小单位,块大小、块长、行数往往指的是这一块存储信息的位数

组:组是一个或多个行的集合。在直接映射中一组由一行组成,组相联映射中一组由多行组成

tips:这里有一个很重要的误区!!Cache块中存放的就是实际使用的数据,而不是主存地址。例如,主存块的大小为4B,计算机按字节编址,说明这一块中存放了4个1B的信息,需要4*8=32个bit位来存储,故数据位的位数为32.

再tips:我一开始不理解一口气把4个1B的信息放进去,如果行内不存储块内地址怎么找到具体对应的哪个信息呢?后来查阅资料了解到,是根据CPU提供的地址内的偏移量(其实就是块内地址)查找,所以行内不需要存储具体的块内地址,举例如下。

这里我们不关注怎么找到这一Cache行的,只关注找到行后如何根据cpu给出的主存地址的块内地址找到实际需要的数据,比如这里的块内地址(偏移量)为01,意思就是要从数据位开始向后偏移1个B,这样就找到了实际数据

Cache位数的组成

1.有效位:说明当前Cache行中存放的信息是否有效;

2.标记位:指明这一块是主存中的哪一块副本,和主存的地址直接相关,在直接映射组相联映射中可精简;

3.数据位:块中存放的数据位数,eg:块大小为32B,则共需要32*8=256个bit位来存储;

4.脏位(修改位):回写法使用,标志这这一块是否被修改过;

5.计数器位:LRU替换算法使用,记录主存块的使用情况

总而言之,Cache位数=有效位+标记位+数据位+(脏位)+(计数器位),是否存在脏位和计数器位完全看题目条件,没说就是没有。

主存位数的组成

主存位数的组成较为简单,主存位数=主存块号位数+块内地址位数

块内地址:

主存的块内地址和Cache的数据位(Cache块的大小)可以说是息息相关,首先我们回顾一下基础概念:

按字编址、按字节编址:通常可以理解为主存中的一个地址指向的空间存储了几位的数据

故块内地址的定义:用来标识块内一个数据的具体位置

eg.已知块大小为64B,按字节编址,则块内地址的位数为log(64B/1B)=6位,意思就是只需6位bit位就可以在一个块内找到某个数据的具体位置

eg2.若按字编址呢?

其实含义不变,按字编址,则一个数据的大小为4B,块内地址的位数为log(64B/4B)=4位

主存块号:

Cache和主存划分为大小相等的块,主存能够划分的块的数量需要几位二进制位表示,即为主存块号的位数。

直接映射

定义:主存中的每一块对应唯一的Cache块,若该位置已有内容,则发生块冲突,原来的块无条件被替换出去无须替换算法)。

优点:实现简单;

缺点:不够灵活,即使Cache中有许多空地址也不能占用,发生块冲突的概率最高,空间利用率最低。

在抛出公式之前,我们再加深一下这几个名词的印象:

行号、行数、主存块号

现在可以抛出公式了:

Cache行号=主存块号 mod Cache总行数

eg.已知主存块号为1,8,9,20,24,Cache共有8行,分别对应的Cache行号为?

1 mod 8 = 9 mod 8 = 1,故应存在Cache的第1行中;

8 mod 8 = 24 mod 8 = 0,故应存在Cache的第0行中。

在直接映射中,主存地址=标记位+Cache行号位+块内地址位

Cache 总块数 =2^ n 则主存块号末尾n 位直接反映它在Cache 中的位置,即为Cache行号位
注意:因为我们可以直接根据主存地址中的n位行号位判断出该地址可能存在哪一个Cache行中,所以Cache的位数中无需包含这n位行号位。只将主存块号的剩余位作为标记位即可。
eg.假设CPU访问内存地址0000 0010 0101 0011,按字节编址,主存块大小为16B,Cache中有8个Cache行,,我们来完整推导一下CPU的访存过程:
1.按字节编址:说明一个数据的大小为1B;主存块大小为16B:说明主存块可以存放16个数据,即为2^4个,需要 4个bit位来作为块内地址位
2.Cache中有8个Cache行:2^3个Cache行,需要 3位bit位作为行号位
3.由此我们可得0000 0010 0 101 0011(标记位+Cache行号位+块内地址位)
(以上内容是我们自己根据已知条件推断的,实际上这些信息CPU本来就知道!!)
CPU的访存过程:
首先根据方寸地址中间的Cache行号位( 101),找到对应的Cache行
---->将对应Cache行中的标记与主存地址中的标记位进行对比(0000 0010 0)
---->True:若相等且有效位为1,访问Cache命中,根据主存地址中低位的块内地址位( 0011),在对应的Cache行中存取信息
---->False:若不相等或有效位为0,则“未命中”,此时CPU从主存中读出该地址的一块信息送入对应的Cache行中( 注意,这里是无条件替换,无论这个Cache行之前是否存储过信息,都直接替换),并将有效位设置为1,修改标记位为主存地址中的标记位(0000 0010 0)
---->同时将该地址中的内容送入CPU,访存结束。

全相联映射

图懒得画了,其他人的文章里肯定画了,我这里划水了。

 定义:主存中的每一块可以装入Cache中的任何位置

优点:Cache块的冲突概率低,只要有空闲Cache行,就不会发生冲突;空间利用率高;命中率高。

缺点:标记的比较速度较慢;实现成本较高,通常需采用按内容寻址的相联存储器。

这一映射的实现相对简单,这里我和直接映射进行对比,看有何不同,更容易记忆。

主存地址的结构:

主存地址=标记位+块内地址

显而易见,比直接映射少了Cache行号位,因为在全相联映射中,主存块可以存入Cache的任意行,显然是无法指定行号的。

CPU的访存过程也相对简单:

---->将主存地址中的标记位和Cache各行的标记进行比较

---->True:若有一个相等且有效位为1 ,则命中,根据块内地址从该Cache行取出信息;

---->False:若都不相等,则不命中,此时CPPU从主存中读出该地址所在一块的信息送入Cache

的任意一个空闲行中(若当前没有空闲行,后面讲解的替换算法会告诉你如何进行替换),将有效位设为1,并设置标记,同时将地址内容送入CPU,访存结束。

组相联映射

定义:将Cache分为Q个大小相等的组,每个主存块可以装进固定组的任意一行,是对直接映射和全相联映射的一种折中。

懒虫决定直接贴书上的图

组相联映射的关系可以定义为:

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

组相联映射的主存地址组成:

主存地址 = 标记位+ 组号+块内地址

和之前一样,我们对比着来看:

和直接映射的相似点:直接映射是根据CPU提供的地址内的行号找到对应的Cache行,组相联映射是根据CPU提供的主存地址内的组号找到对应Cache组;

和全相联映射的相似点:全相联映射是根据CPU提供那个的标记位在所有Cache行中寻找相等的标记,组相联映射是在唯一对应的组内Cache行中寻找相等的标记。

over

比较器

接下来我们看一下比较器的概念:

这里我也比较懵,所以引用了一位评论区大佬的总结

袁春风的教材上有提到比较器的概念(408命题组雷神锤),cache在找到对应的组后,需要对组内的每一行逐一进行<tag, valid>的键值对匹配直到成功为止,比较器的作用是通过保存该行的tag部分加快每一行匹配的过程,所以每一个组内有多少行就有多少个比较器,置于为什么不用再乘上组数,我不懂比较器的构造,猜测应该是成本原因。直接映射每个组只有一行,所以只有一个比较器;全映射只有一个组,那么有多少行就有多少个比较器;n路组相联,每一组有n行,所以是n个比较器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值