一.Cache与CPU需要映射的原因
CPU准备访问内存时,会先问问cache存储器有没有已经提前准备好了数据,如果没有则再找内存要:
如果Cache刚好命中,则直接从Cache中读取数据:
如果Cache没有命中(Cache失效),则CPU再去找内存要:
但通常来说,因为Cache(容量小,速度快)和内存的容量(容量大,速度较Cache略慢)不一样,导致Cache和内存记录数据存储方式不一样,而CPU一般只认识内存的记录方法:
所以就有了Cache与内存的地址映射,方便CPU直接找数据:
二.什么是Cache与CPU的映射
Cache的地址映射中,会以Cache的容量为标准将内存分成相同大小的块(页或者区),根据映射方法的不同,地址的表达方式也不同,常见的映射方式分为:直接映射、全相联映射和组相联映射。
三.直接映射
先把映射方式写出来,再详细介绍:
主存映射如下:
直接映射顾名思义,就是直接把内存的地址“直接”原封不动地放到Cache中,但问题来了,Cache可没有主存那么大的容量,怎么“直接”放呢?后来人们就想到一个办法,把内存分成好几区,每一区就刚刚好是Cache的容量大小,根据空间局部性原理和时间局部性原理将不同的区放到Cache中去,如果CPU需求的块刚好存在了Cache里,就说这是“命中了”,如果没有,就说是“失效”了。
如内存容量为1G,Cache容量为8M,采用直接映射方式就可以将内存分为(1G/8M=128)128块,至于128块中要把哪块分到Cache里面去,就是资源调度需要做的事情了。所以,地址映射中就有“区号”(也称之为块)这个部分,让Cache知道这个区块是从CPU哪个地方拿下来的:
但这样做的一个缺点是,每个区块的页都是固定位置的,如主存中每个区的第 0 页,只能进入到 Cache 的第 0 页。若当前时刻 Cache 中 0 号页已被占据,而 1 到15 页空闲,现在要将 1 区第 0 页(即内存的 16 页)调入 Cache 是会发生冲突的。所以直接映像的区块冲突率非常高。
最后举个例子,如果你想找到一本书里面的某个句子,先找到第几章(区号)后,再找是第几页(页号)中的第几段(页内地址),就能找到你所要的句子,这就是直接映射的地址映射方式。
四.全相联映射
全相联映像使用相联存储器(什么是相联存储可以参考我之前写的文章:【计算机组成】三分钟了解顺序存储、直接存储、随机存储和相联存储的区别)组成的 Cache 存储器。全相联映像方式很简单,就是主存的每一页可以映像到 Cache 的任一页。如果淘汰 Cache 中某一页的内容 ,则可调入任一主存页的内容:
没有直接映射方式的分区,是一页一页地放进Cache里面去,所以地址映射比较简单:
全相联映射最大的缺点是采用了相联存储的方式,也就是按内容访问(要是不懂的快去看看我上面发的那个连接!!)的方式进行搜索,在进行搜索时,主存地址不能直接提取 Cache 页号,而是需要将主存页标记与Cache 各页的标记逐个比较,直到找到标记符合的页(访问 Cache 命中),或者全部比较完后仍无符合的标记(访问 Cache 失败)。因此这种映像方式速度很慢,失掉了高速缓存的作用,这是全相联映像方式的最大缺点。如果让主存页标记与各 Cache 标记同时比较,则成本又太高。
五.组相联映射
组相联映射则是集以上两者映射方式之大成,即分区又分组,组内可以随意调换位置,很好了折中了直接映射和全相联映射的最大缺点,同时又拥有自己的新东西(分组),使得CPU读取变得更为灵活。怎么分组呢?就是在分完区之后,再在区块里面分组,分多少组就得看看Cache的容量有多大,分完组后,组内的页可以随意调换位置,没有特定的限制:
组相联映像的规则是:主存中的组与Cache 的组形成直接映像关系,而每个组内的页是全相联映像关系。如主存 1区 0页,他在 0组中,所以只能进入 Cache的 0组中,至于进入到 Cache的 0组 0页,还是 0组 1页,并无强制要求,可任意放置。