文章插图
快取的映射直接映射快取这种快取中,每个组只有一行,E = 1,结构很简单,整个快取就相当于关于组的一维数组 。不命中时的行替换也很简单,就一个行嘛,哪不命中替换哪 。为了适应容量小的情况,第n+1层存储器中的某个数据块,你只能被替换到上一层(也就是第n层)存储器中的某个位置的子集中 。现在假设一个直接映射的高速快取,(S,E,B,m) = ( 4,1,2,4 ),也就是说,地址是4位(16个),有四个组,每个组一行,每个块两个位元组 。由于有16个地址,表征16个位元组,所以总共有8个块,但只有4个组,也就是4行 。只能把多个块映射到相同的快取组,比如0和4都映射到组1,1和5都映射到组2,等等 。这下问题就来了,比如先读块0,此时块0的数据被cache到组0 。然后我再读块4,因为块4也是被映射到组0的,组0又只有一行,那就只有把以前块0的数据覆盖了,要是之后我又读块0,就 miss了,只能到下级的存储器去找 。实际的循环程式中,很容易引起这种情况,称其为抖动 。这种情况的存在,自然大大影响了性能 。所以,需要更好的映射方案 。组相联快取在组相联快取里,E大于1,就是说一个组里面有多个cacheline 。E等于多少,就叫有多少路,所以叫E路组相联 。组相联的行匹配就要複杂一些了,因为要检查多个行的标记位和有效位 。如果最终找到了,还好 。当然,找不到会从下一级存储器中取出包含所需求数据的行来替换,但一个组里面这幺多行,替换哪个行 。如果有一个空行,自然就是替换空行,如果没有空行,那就引发了一些其他的替换策略了 。除了刚才介绍过的随机策略,还有最不常使用策略,最近最少使用策略 。这些策略本身是需要一定开销的,但要知道,不命中的开销是很大的,所以为了保证命中率,採取一些相对複杂的策略是值得的 。全相联快取所谓全相联,就是由一个包含所有快取行的组组成的快取 。由于只有一个组,所以组选择特别简单,此时地址就没有组索引了,只有标记和偏移,也就是t部分和b部分 。其他的步骤,行匹配和数据选择,和组相联原理是一样的,只是规模大得多了 。如果说上面关于这三种映射方法的描述非常抽象,为了能理解得更加透彻,把存储器比作一家大超市,超市里面的东西就是一个个位元组或者数据 。为了让好吃好玩受欢迎的东西能够容易被看到,超市可以将这些东西集中在一块放在一个专门的推荐柜檯中,这个柜檯就是快取 。如果仅仅是把这些货物放在柜檯中即完事,那幺这种就是完全关联的方式 。可是如果想寻找自己想要的东西,还得在这些推荐货物中寻找,而且由于位置不定,甚至可能把整个推荐柜檯寻找个遍,这样的效率无疑还是不高的 。于是超市老总决定採用另一种方式,即将所有推荐货物分为许多类别,如“果酱饼乾”,“朱古力饼乾”,“核桃牛奶”等,柜檯的每一层存放一种货物 。这就是直接关联的访问原理 。这样的好处是容易让顾客有的放矢,寻找更快捷,更有效 。但这种方法还是有其缺点,那就是如果需要果酱饼乾的顾客很多,需要朱古力饼乾的顾客相对较少,显然对果酱饼乾的需求量会远多于对朱古力饼乾的需求量,可是放置两种饼乾的空间是一样大的,于是可能出现这种情况:存放的果酱饼乾的空间远不能满足市场需求的数量,而朱古力饼乾的存放空间却被闲置 。为了克服这个弊病,老闆决定改进存货方法:还是将货物分类存放,不过分类方法有所变化,按“饼乾”,“牛奶”,“果汁”等类别存货,也就是说,无论是什幺饼乾都能存入“ 饼乾”所用空间中,这种方法显然提高了空间利用的充分性,让存储以及查找方法更有弹性 。技术指标CPU产品中,一级快取的容量基本在4kb到64kb之间,二级快取的容量则分为128kb、256kb、512kb、1mb、2mb等 。一级快取容量各产品之间相差不大,而二级快取容量则是提高cpu性能的关键 。二级快取容量的提升是由cpu製造工艺所决定的,容量增大必然导致cpu内部电晶体数的增加,要在有限的cpu面积上集成更大的快取,对製造工艺的要求也就越高