高速缓存存储器与其查询操作

  • 高速缓存存储器
    假设存储器查询地址有m位,那么该存储器会形成M=2^m个地址。相当于一个大数组。
    假设将存储器空间分为一个个高速缓存组。共S个组。
    在这里插入图片描述
    每个组又包含E高速缓存行,每行由三部分组成,分别是数据块有效位标记位
    在这里插入图片描述
    数据块:共B个字节,把块看成数组,每个元素大小为1字节
    有效位:即标记该行是否包含有意义的信息,可以理解为是否缓存了东西
    标记位:唯一标识存储在这个高速缓存行中的块,即标记为的数值不同,数据块中的块是不一样的。
    以下是CPU为查询数据发送给高速缓存器的地址格式。其中t,s,b都需要根据实际情况确定。这里提到的组索引,即表示要寻找的组号。块偏移,即所查找的数据在数据块中的偏移量。
    在这里插入图片描述
    说了这么多,对一些符号标识难免有些混乱,由下面习题加深印象。

  • 下面有两块高速缓存,求空格的数据。在这里插入图片描述
    解:(1)先来看高速缓存区1,总共1024个字节,每组1行,每行数据块有4个字节。
    所以的S = 1024/4 = 256,共有256组高速缓存组。
    m为32即地址为32位,s为组索引的位数,已知有256组,故需要s = log2(256) = 8.
    每个高速缓冲行中数据块有4个字节,即b = log2(4) = 2。需要用2个位来表示块偏移,因为有4块。
    剩下的 t =m-s-b。
    (2)直接可以计算了
    S = 1024/32 = 32;
    s = log2(32) = 5;
    b = log2(8) = 3;
    T = 24;

  • 下面介绍高速缓存器获取到地址后的一个查询过程。
    直接映射高速缓存为例子,该类缓存每组只有一行高速缓存行。(根据行数E可划分为多种高速缓存)
    在这里插入图片描述
    现在假设有一个系统,有1个CPU,1个寄存器文件,1个高速缓冲器L1和1个主存组成。
    当CPU执行一条读取内存字w的指令,它会向L1高速缓存请求这个字,若L1缓存命中,则返回,若不命中,则L1高速缓存需要向主存请求,cpu必须等待。
    高速缓存确定一个请求是否命中,并将其抽取出被请求的字的过程,分为三步:组选择,行匹配,字抽取
    1.组选择
    简单来说利用上述地址中的组索引寻找对应的组。如组索引值为0001,则表示选择组1。组号即为地址。
    2.行匹配
    对于直接映射高速缓存,因为每组只有一行,所以只需要直接看高速缓存行的有效位是否被设置,然后再比较这个高速缓存行中的标记位和地址中的标记位,若匹配则缓存命中。
    3.字抽取
    一旦缓存命中,我们就能确认所求的w位于这个数据块中的某个地方,然后根据地址中的块偏移,得出目标数据在块中的起始地址。

当然在请求的过程中会遇到缓存不命中的情况,这时需要涉及到替换策略。下图为对上述描述的图示。
在这里插入图片描述

在这里插入图片描述
为了加深理解,下面来收工模拟整个过程。
假设有一个直接映射高速缓存,有4组,每组一行,每个数据块两个字节,地址4位。即(S,E,B,m) = (4,1,2,4)。
地址4位,即有缓存有16个字节,地址中组索引占两位,块偏移占1位,标记位也占1位。
即标记有两种,通过不同标记把16个字节分配在4组,共8字节空间中。得下表。
在这里插入图片描述
下图是高速缓存,假设一开始是空的
在这里插入图片描述
(1)请求读取地址0的字,由上表,得知地址0是在组0,但其有效位为0,所以缓存不命中,需要高速缓存区从主存取出数据至于组0中。

在这里插入图片描述
(2)请求读取地址1的字,这次明显缓存命中了,所以直接返回该块。
(3)读取地址14的字,已知地址14在组3中,组3有效位为0,所以缓存不命中,需要重新加载。
在这里插入图片描述
(4)读取地址为6的字,已知地址6在组3中,由上表知组3的有效位为1,但其标记位也为1,而地址6对应的标记位应该是0,所以缓存不命中。所以高速缓存器会重新加载组三上的数据。
在这里插入图片描述

  • 还有其他类型的高速缓存:
    组相联高速缓存
    同直接高速缓存,区别在于有多行,即1<E<C/B。在读取时需要搜索组中的每一行。且替换策略相对复杂,如最不常使用策略(LFU),最近最少使用策略(LRU)。
    全相联高速缓存
    这种高速缓存仅含一个组,即S=1,E = C/B。既然只有一组,那么其地址也不需要有组索引。
    在这里插入图片描述
    全相联高速缓存和组相联高速缓存类似,需要逐行去搜索,区别在于规模。
    由于高速缓存电路必须并行搜索许多相匹配的标记,所以要构造又快又大的相联高速缓存很难,其只适合做较小的高速缓存,如虚拟内存中的翻译备用缓存器,其缓存页表项。

Q:关于为什么要用地址中间位来做组索引?
比如有一段内存,0x0000~0x1111,共16字节。下图分别是以中间位引索和以高位引索,高速缓存区与内存的映射关系。
可以看到,以地址不同位作为索引,组别之间在内存中的映射关系是不同的,组之间的距离也不同。
在这里插入图片描述
以一个char str[16]为例子,该数组分布在上述内存0x0~0x1111中。
假设现在顺序扫描数组,先访问前4个元素,若是高位引索,那么内存中0x0~0x0011都会映射到组1上,访问时需要不停去替换,发生四次缓存不命中,而且只利用到了高速缓存区的四分之一,实用率极低。
但如果采用中间位索引,0x00x0011四个元素分别映射到高速缓存区的组0组3。顺序访问str[0]~str[3]时高速缓存区4个组都被访问到。大大提高了高速缓存区的使用率,也增加了缓存命中率。(每访问4个发生一次缓存不命中)。

参考:《深入理解计算机系统》