本文讲什么?
老样子,在正式开始介绍“高速缓冲存储器”之前,我们先来了解一下其相关的信息。
我相信,上面这张图你一定已经非常熟悉了,没错,这就是在本章绪论说的“存储器的层次结构”。
上一讲我们介绍了存储层次结构中的L4,即主存。继续向上看,你会看到L3、L2、L1都是高速缓冲存储器。那么究竟什么是高速缓冲存储器呢?那就要从“速度”这个关键词说起。
随着计算机硬件行业的不断进步,以因特尔为首的芯片企业造出了一代又一代的高速CPU, 可以说CPU处理数据的速度是越来越快。但是从图中我们能够看到,L0-L6的设备的速度是逐渐下降的,而且速度相差越来越大。
虽然说近年来的存储技术也有进步,但是照着CPU就差远了。这就造成了CPU和主存之间速度差距越来越大。高速缓冲存储器的存在就是为了尽可能的消除这种差距。
在这个存储层次结构中,虽然高速缓冲存储器分为三个档次,但是他们的作用都是相同的,都是起到一种桥梁的作用,不同的只是速度和造价。此外,L1的速度几乎和寄存器的速度相同。接下来,我们来看看高速缓冲存储器在CPU中的具体位置。
这种结构进一步的验证了存储器的层次结构——高速缓冲存储器位于寄存器之下的特点。好了,说了这么多,那让我们来看看高速缓冲存储器的工作原理吧!
高速缓冲存储器(Cache)的工作原理
实际上,Cache的工作原理非常简单,就是利用了映射的方式来获取主存信息。
我们知道,主存的地址范围是2^n(即2^n个字),而每个字都有一个n位的地址。(不明白的可以翻翻这个系列的前几篇文章)。所谓映射,就是两个元素之间的对应关系。而我们很清楚,主存的容量肯定是远远大于高速缓冲存储器的。所以,这种映射必然是一对多的关系,某部分高速缓冲存储器中的内容对应着主存中的的吧部分内容。
为了实现上面所说的映射,我们需要对主存和缓存进行块的划分,使这些“字块”实现一对多的映射关系。简略图如下:
可以看见,我们将主存和缓存划分成了一个又一个的字块,从而实现映射关系。
CPU想要处理信息,首先就是看缓存(高速缓冲存储器)中是否存在信息,如果存在,那么好,就从缓存中读入一个字(一个字块可能包括多个字);如果缓存中没有数据,那么就会根据这种映射关系,将主存中的数据一个字块一个字块地映射到相应的位置,然后再由CPU进行读取即可。
这里有一个名词,叫做缓存命中和缓存不命中。上面说的两种情况中的第一种就是缓存命中,而后一种就是缓存不命中。命中率是衡量缓存的效率的。命中率越高,效率越好。命中率=缓存命中/(缓存命中+缓存不命中)。
上面说的例子,可以理解为映射中的第一种方式——直接相连映射。下面我们就来详细的了解一下映射方式。
主存——高速缓冲存储器之间的映射方式
直接映射
下图给出了直接映射的示意图:
直接相连映射可以说是一种最简单的方法,为什么这样说呢,因为他的逻辑最为清晰、也是最好理解的一种映射方式。
你可能会说,这么复杂的一个图你跟我说这是最简单的方法,你怕不是个傻子吧!不要急,听我慢慢说。
首先,先看Cache,Cache被分成了2^c 块,而主存则被分成了n*2^c, n就是n组,从图中的连接线可以很直观的看出,主存中的字块0~2^c-1 块对应着Cache中的0~2^c-1 块。而主存中的2^c 块则是对应着Cache中的第0块,依次类推。即主存中的每一组字块对应着Cache中的相应字块。
好了,对应关系说完了,我们来解释一下图中的其他内容。
首先说标记,标记代表的意义就是当前Cache字块中的数据是否有效。可以这样想,我们之前讲了缓存命中和缓存不命中,当CPU向缓存推送地址,说“我想拿到Cache中字块0上的数据”,那么好,Cache首先要看看字块0上的标记位是否为1,如果是1,就把这个数据给CPU,这就叫缓存命中;如果标记位为0,则说明此时Cache上的数据无效,则不推送,这就叫做缓存不命中。你可能会这样想:Cache上的数据不都是从主存上拿到的吗,为什么还会有无效的时候呢?这样的例子不少,比如说Cache刚通电的那一瞬间,这时候Cache上面是没有数据的,标记位的0就起了很大作用。如果发现是0的话,接着主存会向Cache推送数据的,这一点不必担心。看到这,我相信你肯定也知道比较器是个什么玩意了。
全相联映射
如果说直接相连映射是最简单的方法的话,那么全相连映射就是一种最粗暴的映射方式。还是先看图:
我相信你此时一定知道我为啥说这是一种相当粗暴的映射方式了,没错,看到那交错纵横的线,一开始我是拒绝的,这货太暴力了。
标记位自然是不用说,主要是这货的主存不分组,主存中的任何一个字块都可以映射到Cache中的任何一个字块,所以看起来十分的凌乱。但是还是有好处的,你看直接映射,比如说主存还是分成n组,也就是说Cache中的每一个字块都有n个主存中的字块对应,且主存中的字块只能对应Cache中的一个字块。所以说,如果Cache中的数据没有失效的时候,主存中的其他的n-1个字块都是需要等待的。
但是全相联映射不同——主存中的字块可以对应任何一个Cache中的字块,也就是说,如果主存想要向Cache推送数据,只需要挑一个失效的地方,将原有数据覆盖即可。
这种方式比较混乱,电路可能会很复杂,同时又会造成较高的成本。
组相联映射
计算机组成原理很有意思,你会发现,在计算机结构的设计方案中,一般都是这样的:有一种比较简单的方案,但是效率并不怎么好,然后有一种效率很好的方案但是可能过于复杂,接着就会出现第三种方案,一般这种方案都是以上二者的折中。在有效的消除了二者的缺点的同时,又极大的利用了二者的优点,不得不感叹这些科学家的聪明才智。
首先说对应方式,组相联的映射方式和直接相连的映射方式相同,都是主存中的每一组字块中的每一个字块对应着Cache中的一个相应字块,但是有不同之处在于,Cache中的字块分成了两组,这种方式也叫做二路组相联。
其次说下这种连接方式的优点:可以看到,在二路组相联中,除非是Cache中每块的两组字块都被占用了,否则不存在冲突的问题,这大大提高了效率,同时又没有全相联那种暴力的方式。
总结
本文详细的讨论了Cache的工作原理及三种映射方式,希望对大家有所帮助。
如果你喜欢我的文章,请帮忙点赞;如果你对本文内容存在疑问,请留言告诉我。您的点赞和留言是对原创作者的最大支持,感谢您的阅读。
此外,本人一直在寻找志同道合的小伙伴,同样如此的可以邮件联系我:roobtyan@outlook.com.
本人微信公众号: