高速缓冲存储器:Cache.Cache的功能是提高CPU数据的输入和输出的速率.CPU的速度与主存的速度之间有巨大的差异.主存的存取时间、存取速度要比CPU的速度要慢了很多倍.为了调和它们之间的巨大速度差,改善整个系统的性能,那么我们就提出/采用了Cache.Cache是一种存取速度非常快的一种存储器.
Cache之所以能够改善性能,它的依据是程序的局部性原理.这个原理我们在操作系统部分已经提到了,这个原理也就是说系统在80%的时间或者是更多的时间在使用程序当中20%甚至是更少的一个比例的一个数据.
正是有这个理论为基础,Cache才能够改善系统的性能.因为Cache的大小比起主存来说实在是太小了,Cache一般是128KB,512KB,而主存现在已经达到了500多MB.这样子Cache和主存之间这个大小就相差了近千倍,如果没有程序的局部性原理,如果说一个程序的运行过程中所有语句要使用到的一个频率是相等的,那么Cache也就难以改善系统的性能了.
第二点是命中率,这一块考的比较多.也就是给你一个Cache的命中率,然后让你计算系统平均的一个存取周期.命中率它是一个什么样的概念呢?因为系统中有主存,有Cache,Cache速度非常快,而主存速度相对来说比较慢,Cache当中存的内容只是主存当中的一个映射,而且是一个很小集合的一个映射.Cache当中有的数据主存中全部都有,而Cache中没有的数据主存中也有.这个Cache相比主存而言它主要就是速度非常的快,所以在这种情况下当CPU要用到一个数据的时候,如果Cache中有,我们就不到主存去调用数据,而访问一个数据的时候能够直接从Cache里面读取数据的那种访问,我们就称为访问命中.
而其他的部分Cache当中没有的,主存中有的,我们要到主存里面去读取数据,这种页我们称为未命中的一种情况,就是失效的一种情况.那么平均起来,系统的一个平均存取访问的一个时间,如何来计算呢?
如果说h是90%,90%的数据可以从Cache中访问,而t1表示的是Cache的周期时间,也就是从Cache当中读取一个数据所要花费的时间,t2表示主存存储器的周期时间,也就是在主存当中存取数据所要花费的时间,然后现在要求的就是"Cache+主存"的一个平均访问的一个时间,平均周期.那么平均周期的计算方法是这样子的,就是用Cache的访问命中率*它的存储周期+(1-命中率)*主存的存储时间/存储周期.这样子就能够得到系统平均的一个访问周期.
例题:
再来看一个例题:软考当中的原题.
多次进行平均存取周期的计算.1μs(微秒)=1000ns(纳秒).一定要把这个关系给换算出来,要换算到和这个Cache同样的大小,同样的单位,如果单位不统一计算出来的结果肯定是错误的,
P=0.6,Cache的命中率是60%.让你求出三个处理机在命中率为60%的情况下它们的平均存取周期是多少?求出了这个周期,周期越短的速度越快,那么我们就看怎么来求,就用开始的公式,命中率h是60%,就是0.6,然后求处理机A,处理机A它的这个Cache存取周期是60ns,主存的存取周期是1μs,也就是1000ns.然后我们就用60ns*0.6+1000ns*0.4就可以得到A它的一个平均的存取时间/存取周期.
C它的效率是最高的,速度最快的,B排第二,A排第三.命中率P=0.75的时候也是这种计算方式.
D和E是同一类题型.命中率P为什么值的时候,处理机A和处理机B它的处理速度会最接近.最接近就是A和B它的平均存取周期两个值最接近.两个值最接近可以理解为A的平均存取周期-B的平均存取周期的绝对值最小的一种情况.最小是什么情况?就是等于0.
Cache的读写过程也可以说是Cache它一个数据的一个更新的一种方式.在什么情况下Cache的数据会更新到内存/主存当中来?因为我们知道Cache是主存的一个映射而已,而CPU操作的时候Cache中有的数据系统不会再到主存中去进行读取和操作.那么就意味着有可能对Cache进行写数据、修改这个数据,而修改的数据我们什么时候应该要把它更新到主存当中去呢?这就是一个读写、就是Cache的读写过程,所谓讲的一个内容.它这种更新方式有三种.
一种是写直达:系统要对Cache进行写操作的时候,这个数据同时被写到了主存当中.每写一个Cache数据,它就写回到主存当中.每写一个,就写到主存当中.这种方式其实效率是不高的,因为它老在写主存我们知道主存的速度又不怎么快,而且还有这种情况:就是本身修改数据只是一种临时性的一种活动,这个数据老是要被修改的比如说它是一个temp值,一个临时的值,是一个中间变量,一个中间变量它可能每做一步小的操作它要进行更新,如果这些更新直接就被更新到了主存去了,那可能就造成了系统过多地去访问主存,去修改主存的数据,而使整个的性能下降,速度降低.
第二种方式:写回.CPU修改Cache当中的某一个数据之后,....Cache丢弃之后我们就把这个数据写到主存当中去.这种方法就会比写直达的方法效率高一些.
第三部分:标记法.对Cache的每一个数据都设置了一个有效位,当数据进入Cache之后,有效位就置1.如果说CPU要对这个数据进行修改,那么数据就写入主存储器,并且同时将这个有效位清0.大家可能就会产生疑惑了:我直接把这个数据写到主存当中去,那么我们Cache里面数据它还是没有得到更新.确实如此,所以它有另外的一个操作来避免错误,就是说Cache当中如果已有的数据它的标识为0,那么系统会从主存中去调取数据,而不会直接读Cache当中的数据.因为标识为0代表Cache中的数据和主存中的最新数据不一样,不一样所以我们就要取主存中间的数据过来.
Cache的地址映射:有三种方法.
和操作系统部分讲过的页式存储有相似之处,它这里也是进行分页,
Cache的页的大小必须要和主存的页的大小相等.所以8MB就要划成16页,每页512KB.
下面具体来看看这几种映像方式.
直接映像是一种最简单、最直观的映像方式.直接映像就是将Cache分页,也将主存分页,但是我们都知道这个主存肯定比Cache大了很多,所以主存不断要分页而且还得分组、分块,也可以说是分区.
比如说主存有2048页,而Cache只有16页,这个主存有0-2047页.也就是我们刚开始说的主存有1GB的内存,每一页512KB.而Cache只有8MB,也是512KB一个页所以它有16个页.在直接映像方式当中,就做了一个要求,就规定死了主存当中每一组它的第0页只能够放入Cache当中的第0页,主存的这个第16页是相对于整个主存而言的,但是其实相对于第1组来说这个第16页就是第1组的0页,17页就是第1组的第1页,而第31页就是第1组的第15页.因为每一个组它有16页,从0号-15号页,每一组当中的第0页只能够调入Cache的第0页,即使当前第0页被其他的已经占用了,比如第127组这个页占用了Cache的第0页,这时第0组的第0页要进入,就无法进入.但是如果第0页它想试图进入这个第1页这个空页面,那是不允许的,即使它们其他的都空了,也不允许第0页进入它这些页面.所以相对来说比较固定.主存的第0页就只能够放入Cache的第0页,这种方式是比较简单的,也是比较直观的.然后要进行比较,计算Cache的地址都非常的简单,要计算Cache的地址的话,Cache的地址就是主存地址的一个部分,
就比如说我要把它记录下来,记录主存的第0组第0页是否在Cache当中,我们只要记录进行简单的判断就可以了.就直接判断这个是对应Cache第0页的,这个对应Cache第1页,这个对应Cache第2页、第3页,一直到15页.这个里面就记录了就这么一个表格,记录了这个主存的组号,它如果说记录了Cache的0号页对应的是第1组,那么我们就知道第1组这一个页面在Cache当中,如果这里记录的是第127组,那么我们就知道这一个页面在Cache当中.很容易判断,只需要记录一个量就可以进行判断了.
全相联映像就没有这么直观了.全相联映像也是进行分页,分页之后它也有一张表格进行记录.记录的格式是怎样的呢?
就是主存的页号、Cache的页号这么来对应.因为在这里,任何一个主存页它都可以存入任意的一个Cache块当中.所以我们这里要记录主存页号和Cache页号的一个对应,然后要判别某一个页是否在Cache当中也比较麻烦.因为主存的页号它的长度是比较长的,进行查找起来也没有前面的那个那么方便.而且从主存的这个地址难以确定它在Cache中的地址.
下面我们再看组相联.组相联其实和直接相联、全相联是有着密切关系的.组相联是直接相联、全相联的一个组合体,组相联要对主存分区,还要分组,先分区再分组,区的大小就和这个Cache的大小是一样的.Cache中要分组,比如说两页,每两页分一组,主存中也这么分组,然后它映射的一个要求是这样子的.分了区之后分组,组有指定的要求,比如说第0区的第0组,只能够放入Cache的第0组,不能放到第1组,也不能放到第2组,这个就是利用的直接相联的一种方式.第1区的第0组也只能够放入Cache的第0组,一直到最后,比如说到127区,它的第0组也只能够放入Cache的第0组,然后每一组中有多个页面,0号页面,1号页面,这个就比较灵活了,并不是说0号页面一定只能够放在Cache的0号页面里,主存的这个0号页面它可以放到Cache0组的0号页面也可以是1号页面.所以它在组内是一种全相联的一种方式.
大家注意这个图是0101,和某些教材上面画的有些不同.但是这种方式是更为科学的.因为首先是分区,地址,一个连续的一个主存地址,前几位就作为了区号,再分组,分两组的话,区里面分了8个组,所以组号要占掉一些,然后组里面再分页,这个页号,因为只有两个页面,每一组里面只有两个页面,所以页号只有1,只占1位.在里面就是页内地址,这样子来计算的话,每个组里面只有0和1两个页面.这样下来这个第127区第7组的第1号页面就是内存当中的最后一个页面,也就是内存中的第2047页.这边的最后一个第1页,是第7组的第1页,它是Cache中的最后一个页,它是Cache中的第15页.然后这个里面,在组相联的方式里面,要进行记录才能够找到才能够确定某一个我要访问的内存块是不是在Cache里面.要判断这个信息就要找到要记录主存的区号,另外就是主存的页号和Cache的页号,只有这三个量才能够确定内存中的某一个块是不是在Cache当中,如果是在Cache当中,是在Cache的什么位置.