在一切开始之前,首先最重要的是需要去明白和掌握内存的块的定义:内存被分为若干块,这些块:1.大小相等,2.每块由若干字组成,3.块的长度成为块长,块的长度是指由几个字组成就是多长,比如一个块由x个字组成,那么块长为x.4.每个块由连续的字组成。在Cache中这种块被某些替换原则替换进入Cache之后,称为Cache的行(有些书上也称为块,这里就用行表示,以免混淆)。有以下几个特点:
1.块长(一般是取一个存取周期内从主存调出的信息长度,和交互存取有关系)与行长相等,这点和物理页和逻辑页的页内地址的长度是一样的原理类似。
2.Cache中行的位数=行号+行内地址 内存中块的位数=块号+块内地址。
3.块内地址的位数由块的长度决定(设块的长度为x,块内地址的位数其实就是用几位能表示x的问题),块号的位数由块的数目决定(比如块的数目是x,块号其实就是用几位二进制数能表示x个数的问题),行号的位数由行数决定。块里的内容就是行的内容,行内地址和块内地址相同。、
标记位是什么?先记住一点,标记位和cache的地址没有一点关系。每个行对应一个标记位。后面会进行说明

CPU与内存以及Cache之间的交互方式

好了,明白了块和行的定义之后,我们来看看CPU与内存和Cache之间的交互:1.CPU同时(也有可能不是同时,这时事先访问cache cahce里面没有再对主存进行访问,如果缺失的话访存时间会长一点)向Cache和内存发出读请求。把地址同时送给Cache和内存。2.Cache控制逻辑(由硬件实现)判断此内存地址是否在Cache中,在则立马将此内存的字送给CPU,与此同时,终止访问内存。3.若不在Cache中,用主存读取周期从主存中将字取出送往CPU,与此同时,把含有这个字的整个数据块通过Cache与主存的直接通路送到Cache中。(由这个交互过程我们可以看到,主存和Cache与CPU交互的时候传送的是字,但是Cache和主存交互传送的是块)
了解了过程之后我们来看看映射关系是什么,映射关系是CPU在访存时,将主存地址变换成Cache地址的过程。对应第二步的判断是否在Cache中的其中一部。
三种映射关系。1.直接映射。2.全相联映射。3.组相联映射。
1.全相联映射
将块内地址直接变为Cache的行内地址,同时将块号直接放进Cache的标记位(这个时候标记位就是内存地址的块号)里去,直接将主存里的一个快包括内容直接拷贝到Cache里的任意一行里去(一般是弄成连续的),这样相当于相当于建立了一个标记位和行之间的对应关系表,访问一个内存地址上的字,只要从内存地址中取出块号,然后在标记位和行之间的对应关系里查表,就能找到这个字所在的行,然后用快内地址(其实就是快内偏移量)找到行中对应的字的地址。
例如,主存现有256个块(得出块号为8位),每个快有256个字(得出块内地址8位),所以内存地址总位数为16位,所以cache块内地址应该有8位,设它有8行,行号有3位,所以cache地址长度为3 + 8 =11位,标记位为块号。可以随便映射到任意一个Cache的行,建立这个块号(也就是标记位)与映射到的行的对应关系,标记位的内容为块号(即内存地址的前八位),这个就是简单的全相联映射。 此时,主存容量为块数(256)*块长(256)为64K,Cache容量为行数 (8)*行长(256)为2K(不包括标记位)。(为什么是K 不是KB?其实写成64KB 2KB也可以,毕竟表示的是容量,写成64K 2K就意味着,有64个字的容量,或者有2K个字的容量,因为有些计算机一个字可能不是8位。本例子中是一个字8位)
如何访问内存中一个字怎么找到他对应的cache的地址呢?(由硬件实现),有一个比较器,1.CPU访问按内存地址,将其块号放到比较器中,然后比较器将块号和标记位与行之间的对应关系表中的标记位一个一个比较,如果有一个标记位和块号一样,则说明这个字所在的块在Cache里,然后用地址的低八位(快内地址,也叫做快内偏移量)找到行中的那个字的地址 然后读入CPU。2.如果没有标记位和块号一样,说明不在Cache里,通过16位地址直接访问内存送CPU,同时将这个字所在的块整个搬入Cache里(硬件实现)。这种方法命中率高,但是比较器电路设计复杂。因为对应关系表中一个标记位就要连一条线,最简单的比较器就是两个数比较最简单,所以有了直接映射。