储器层次结|「计算机组成原理」:高速缓存存储器( 二 )


文章插图
当一条加载指令指示CPU从主存地址A中读取一个字w时,会将该主存地址A发送到高速缓存中,则高速缓存会根据以下步骤判断地址A是否命中:

  1. 组选择:根据地址划分,将中间的s位表示为无符号数作为组的索引,可得到该地址对应的组。
  2. 行匹配:根据地址划分,可得到t位的标志位,由于组内的任意一行都可以包含任意映射到该组的数据块,所以就要线性搜索组中的每一行,判断是否有和标志位匹配且设置了有效位的行,如果存在,则缓存命中,否则缓冲不命中。
  3. 字抽取:如果找到了对应的高速缓存行,则可以将b位表示为无符号数作为块偏移量,得到对应位置的字。
当高速缓存命中时,会很快抽取出字w,并将其返回给CPU。如果缓存不命中,CPU会进行等待,高速缓存会向主存请求包含字w的数据块,当请求的块从主存到达时,高速缓存会将这个块保存到它的一个高速缓存行中,然后从被存储的块中抽取出字w,将其返回给CPU。
注意:为了使得地址中的b位能够编码块偏移量,要求从下一层存储器中,根据块偏移量的值从中截取出块大小的数据块。
该编码方式具有以下特点:
  • 能够通过组索引位来唯一确定高速缓存组
  • 映射到同一个高速缓存组的块由标志位唯一地标识
  • 标记位和组索引位能够唯一的表示内存中的每个块
  • 有可能会存在多个块映射到同一个高速缓存组中(只要地址的组索引相同)
可以根据每个组的高速缓存行数E,将高速缓存分成不同的类型
1.1.1 直接映射高速缓存

储器层次结|「计算机组成原理」:高速缓存存储器
文章插图
如上图所示,当 E = 1E=1 时,高速缓存称为直接映射高速缓存(Direct-mapped Cache),每个高速缓存组中只含有一个高速缓存行。
当缓存不命中时需要进行缓存行替换,会先从下一层的存储器中请求得到包含目标的块,然后根据地址计算出高速缓存组的索引,然后由于一个组中只含有一个高速缓存行,所以会直接将该块替换当前的块。
这里需要注意的一点是:当程序访问大小为2的幂的数组时,直接映射高速缓存中通常会发生冲突不命中。
1.float dotprod(float x[8], float y[8] )
2.{
3. float sum = 0.0;
4. int i;
5.
6. for(i = 0;i < 8;i++ )
7. sum += x[i] * y[i];
8. return sum;
9.}
我们首先假设数组x排在数组y之前,且x的地址从0开始。然后直接映射高速缓存的 b=2b=2 和 s=2s=2 ,即有两个高速缓存组,每个高速缓存组有一个高速缓存行,每个高速缓存行能保存16字节数据块,即4个浮点数,则高速缓存容量为32字节,我们可以得到高速缓存对地址的划分如下所示(64位系统中)