阅读本文前,请确保自己已经了解了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中的任何位置
优点: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个比较器。