有点迷茫

V1

2022/07/20阅读:14主题:默认主题

Cache映射的三种方式

计算机存储层级结构

上图是计算机的存储的层次结构图,自上而下,运行速度越来越慢,存储容量越来越大

其实CPU在运行时,所需要的操作数大多数是来自寄存器的,速度是很快的,而离CPU越远的,运算速度越慢

就我个人的理解,cache就是我们CPU内部的SRAM,主存是DRAM,也就是我们经常听说的内存条,外存储就是硬盘之类的

我们应该了解,计算机在运行时,操作指令多存放在主存(内存条)中,再结合上图可以发现,主存并不是离寄存器最近的存储器件,那么为了提高计算机的速度,应当将运行指令先从主存中拷贝到cache中,对DRAM和SRAM有过了解的小伙伴应该知道,SRAM运行速度快,但成本高;DRAM运行速度相对慢,但是价格相对便宜,因此cache的容量必定不会与主存的容量大小相同

那么如何保证从主存拷贝到cache中的指令和数据正是我们所需要的呢?

这就涉及到了程序访问的局部性

程序访问的局部性

分析结果表明:

在较短时间间隔内,程序产生的地址/所访问数据往往几种在存储器的一个很小范围内

程序访问局部性可以分为:时间局部性和空间局部性

  • 时间局部性:刚被访问过的存储单元很可能不久后又被访问
  • 空间局部性:刚被访问过的存储单元临近的单元很可能不就后被访问

这里再来介绍个概念

CPU和cache之间是以进行指令/数据的传输

主存和cache之间是以进行指令/数据的传输,每个块中又包含多个字(单元)

当CPU要从主存中读取指令/数据的时候,会先查看cache中有没有,如果有直接调用cache中的指令/数据,如果没有则先从主存中拷贝到cache中,在从cache中调用

从两个局部性分别来看

  • 时间局部性:对于从主存拷贝到cache中的指令/数据,如果不与映射方式冲突,不会在CPU调用完后就立即擦除(映射方式接下来会介绍),可以理解为,被CPU调用的指令/数据还是保留在cache中,如果下次再次调用这些指令/数据,它们还在cache中,不用从主存取
  • 空间局部性:因为从主存中拷贝到cache中的指令/数据是以块为单位的,假如说一个块中有10个数字,刚开始CPU想访问在数字1位置的指令/数据,而cache此时将数字0-9都拷贝进cache中,那么下次CPU想访问在数组5中的指令/数据时,它们也都在cache中

cache与主存的映射

cache与主存可按三种方式进行映射:直接映射、全映射、组映射

直接映射

(直接从网上的视频中摘个题目)

from MOOC
from MOOC

因为主存和cache之间是以块为单位进行传输的,因此cache和主存中每个块的大小要相同

from MOOC
from MOOC

这是直接映射的示意图

从题目中给的计算结果看,cache共分为16个槽(也叫行),主存共分为2048个块

将主存的块根据cache的槽数进行块群的划分

128个块群是由主存的2048个块 / cache的16个槽得来的,主存中每个块群有16个块

直接映射就是每个块群的第几个块只能映射到cache的第几个槽中

这么说有点抽象,换个说法

0块是0块群的第一个块,那么0块就只能映射到cache的第一个槽(0槽);16块又是1块群中的第一个块,那么16块也只能映射到cache的第一个槽(0槽)

在介绍局部性的时候,我有提过“如果不与映射方式冲突”,试想一下,按照直接映射的方式,CPU第一次访问的是主存的0块,下次访问的是主存的16块呢

接下来介绍地址

from MOOC
from MOOC

从这个图中可以看到,地址分为:主存地址、主存块号、主存标记、cache槽号、块内地址和cache地址

  • 块内地址指出来每个块中访问的是第几个单元

  • cache槽号指出存储在第几个槽中

  • cache槽号指出指令/数据存储在cache中第几个槽的第几个单元中

  • 主存标记指出访问的是主存中的第几个块群

  • 主存块号(主存标记+cache槽号)指出访问的是主存的第几个块

比如我们要对0220CH单元进行访问

0220CH转换成二进制是 0000_0010_0010_0000_1100B

主存标记是前7位 -> 0000_001 (1块群)

cache槽号是主存标记后面的4位 -> 0_001 (1槽)

块内地址是最后的9位 -> 0_0000_1100 (12单元)

主存块号是前11位 -> 0000_0010_001 (17块)

即0220CH单元是主存中1块群1块(17块)中的12单元

直接映射访问方式:

假如CPU想访问主存0块中的12单元,CPU先查看cache的0槽(0块应当映射到0槽中)是否存在0块的内容,如果没有则先将主存0块中的内容拷贝到cache的0槽,在从cache中访问

试想一下,假设我们的cache固定,就是16个槽,如果我们的主存非常大,要分很多块群,是不是就大大增加了hit cache同一个槽的概率了

这也是直接映射的缺点

全映射
from MOOC
from MOOC

全映射是主存中任意一个块都可以映射到cache中的任意一个槽中,没有主存的某个块只能映射到cache的一个槽中的限制

因此,对于全映射的地址来说,主存地址中不存在cache槽号的内容

全映射访问方式:

假如CPU想访问主存0块中的12单元,CPU会从cache的0槽到15槽依次查看0块是否映射到cache中,如果都没有,主存才会将0块映射到cache中

试想一下,如果cache的槽号非常多,CPU每次要访问主存中的某个块里的单元,都要先将cache中的每个槽先查看一遍,是不是很浪费时间

组映射

组映射可以理解为是直接映射和全映射的结合体

from MOOC
from MOOC

在组映射中,会将cache进行分组,每组cache又会存在几个槽

组映射时,主存和cache的组之间映射是直接映射,与cache组中每个槽之间的映射时全映射

就像之前的例子,我们将cache的16个槽分为8组,每组有2个槽,那么在进行组映射的时候,主存在中块会先与cache的组进行直接映射,在确定要映射的组后,再与组内的两个槽进行全映射

from MOOC
from MOOC

这里地址中的标记位指出对应槽取自主存的哪个组群

联想刚才在全映射和直接映射提出的两个极端的情况:

  • 如果主存很大(块多),主存的块hit cache同一个槽的概率增大,而在组映射的情况下,主存的块hit的是cache的组,而cache的组内有多个槽,主存的块可以存放在cache组内的任何一个槽中
  • 如果cache很大(槽多),CPU要访问主存的某个块时,只需要先在cache的固定组中查看这个块是否存在即可
对比三种映射的地址

直接放图吧

分类:

其他

标签:

其他

作者介绍

有点迷茫
V1