对缓存的思考——提高命中率
在提高程序性能、何为缓存中提到:早起的cpu存储层次只有三层即cup的寄存器DRAM主存和磁盘存储。因为寄存器和主存之间的访问时间开销差距很大于是设计者在寄存器一个时钟周期和主存之间加入了L1缓存2——4个时钟周期后来由于L1缓存和主存之间的差距又在主存和L1之间加入了L2缓存当然后面还有L3缓存等等。在这里为了简单起见假设CPU寄存器和主存之间只有一个L1缓存。下图是高速缓存存储器的典型总线结构:缓存结构下图清晰的说明了通用缓存的组织结构:可以看到缓存内部是以组的形式组织的。图中的每一块代表一组每组由一到多行组成当然图中的是每组有多行。每一行包括1 位标记位valid bit标明这行的信息是否有可用t 位的标记标明它是属于这一组的哪一行剩下的空间是存储数据的数据的空间可以看出在下面的图中把数据地址分为了三部分左边 t 位是标记行号的中间的 s 位标明组号最后的 b 位则是数据块在行内的偏移量。通常来说缓存器可描述为(S; E; B; m)其中S为缓存中的组数E为每组的行数B为每行存储的字节数m为缓存的地址位数。所以缓存的容量为CS*E*B。从缓存中取数据这个过程在上一篇博文中就有简单的介绍当cpu需要从主存中取出地址为A的数据时先把地址A发送给缓存如果缓存中存有地址为A的数据就从缓存中取出该数据传给cpu。那么缓存是如何知道自己是否存有地址为A的数据呢这就和缓存的组织有关系了上文中缓存把地址组分为了三部分t 、s 、b。所以只要简单的检查地址中的数据位就能判断该地址是否在缓存中如果在的话还能确定该数据的位置。参数 s 、b 、m 把m个地址位分为三个字段。如下图:下面的详细的寻址过程地址A中的中间S 位标记了该地址在缓存中属于哪一组先通过s 确定这个地址在缓存中的哪一组。通过上面一步确定了属于的组后地址A中的左边 t 位标记了该地址在该组的哪一行。最后由右边的 b 指出地址A中的元素在该行的偏移位。也就是确定在这行的哪一个位置。CPU从主存中读数据的详细过程和上文中说的一样这里假设计算机的存储结构只有cpu寄存器L1缓存主存。当cpu执行一条读存储器地址为A的指令它向高速缓存请求该地址如果缓存命中缓存很快返回数据。如果缓存不命中L1缓存向主存请求该数据在这期间cpu必须等待。当被请求块从主存到达缓存L1时L1缓存将数据放在他的一个高速缓存行里然后将数据从行中提取返回给cpu。也就是说如果缓存不命中先要把数据存入缓存再返回给cpu。概括的说高速缓存确定一个请求是否命中有三个过程1、组选择2、行匹配3、字抽取下面将会结合具体情况说明这一过程。直接映射高速缓存现在已经知道我们用(S; E; B; m) 来描述缓存这里就根据其中的E也就是一组的行数 把缓存分为不同的类别。当E1 时也就是说每组只有一行的缓存组织形式我们称为直接映射高速缓存。因为容易理解先对它进行介绍。图片来源 《computer systems》正如上图所示直接映射高速缓存中每组只有一行。直接映射高速缓存中取数据下面将以直接映射高速缓存为例一步步说明cup从高速缓存中取数据的过程。1、组选择如上图所示缓存从地址A中抽取出中间的s 位这 s 为的数值就标记了该地址所在的组。这里可以把缓存当作是一维数组其中每个元素是一个组而地址中的 s 位则是这些组的索引。如图中的组标记为 0001 对应组 set1。这要把地址中间的 s 为提取就能得到该地址在缓存中对应的组。2、 行选择选好组 i 之后就是确定地址A在组 i 的哪一行。因为直接映射缓存的每一组只有一个行。所以只要看A地址中的行标记是否和缓存中的行标记位匹配。匹配则地址A中的数据在缓存中。3、字抽取既然已知道了地址A中的数据在缓存中的位置最后一步只要更具地址A中表示偏移量的位从缓存中取出数据即可。如下图所示直接映射高速缓存不命中当缓存不命中的时候就要从下一层存储中取出数据放入缓存的某个位置中放入的位置就由请求地址A中的组索引确定所在缓存的组行所以确定应该放置的行。如果组中的行都是有效缓存行了就必须要驱逐现有的一个行。对于直接映射高速缓存每组包含一个行替换策略就变的很简单用新来的行替换当前行。直接映射缓存寻址示例通过上面的介绍已经基本了解了缓存的组织形式以及如何从缓存中取出数据但是上面都只是理论上的阐述。为了能更好的了解这里会有一个具体的示例。诚然学习一种只是最好的方式就是应用它。 如果你已经对上面的知识有所了解那么请继续吧。下面的内容会让你更清楚的了解到缓存工作的机制。假设我们有一个直接映射的高速缓存描述如下(S; E; B; m)(4;1;2;4)也就是说:该缓存有4个组s4每组有一行E1每一块有两个字节B2存储器的地址是4位的m4该状态有图描述如下:其中最左边的一列是地址中间的三列是地址的二进制表示形式。最右边的一列是虚拟存储器的块的标号。和上文中说的一样缓存寻址时把地址分为了三个部分。分别表示该地址在缓存中所在的组、行、以及偏移。和上图所对应是四位的地址行其中最高的一位标记所在的行因为是直接映射高速缓存每组只有一行所以一位就能表示。组中间的两位表示地址所在的组。从图中可以看出拥有相同组的地址有四个比如组号为00 的地址有四个为0、2、8、9偏移偏移位由最右边的一位表示。每行中有两个数据块所以偏移位用一位也就能表示。看这个表的时候有一点提示中间的三列其实是第一列地址的二进制表示形式。下面是对这个特定缓存的一点分析(S; E; B; m)(4;1;2;4)该缓存有四个组每组一行。有图中可知要放入缓存的地址为16个。所以每组对应四个地址。在图中的表现就是四个相同的地址有相同的组索引。每行有两个数据块用地址最低位表示0表示第一个1为第二个。看组索引为00的地址为0 、1 和 8 、9。0和1有相同的行标记08和9有相同的行标记1.所以地址为0、1的数据要么都在组00中要么多不在。地址为8、9的也一样。说明了0、1是一个整体8、9也一样。如果在都在不在都不在。这两个整体通过最高位标记为来标明。下面是寻址实例刚开始时缓存是空的也就是还没有预热如下图所示1读地址0的字地址0的为 0 00 0 对应缓存中第0组行标记位为0的偏移为0的位置。显然现在缓存还是空的标志位 valid 都为0。缓存不命中所以缓存先从下一级的存储中取出改行对应的所有地址的元素放入缓存中。也就是地址为0 和1 的元素。然后再从缓存中取出数据m[0]传递给cpu。进过对地址0的读操作后缓存的组织情况如下所示这也验证了上文的说法地址0 和1 是一体的他们要么都在要么都不在。因为他们有相同的组索引、行索引。2读取地址1的字地址1为0 00 1 对应缓存中的第0组行标记为0偏移为1。这次缓存命中从缓存返回m[1]3)读地址13的字地址13为1 10 1 对应缓存中的第2组 行标记为1 偏移为1。同1一样缓存不命中从低一级存储中取出 组索引为10 行为1 的数据放入缓存然后返回m[13]对地址13进行操作后的缓存情况为4读地址为8的字地址8为 1 00 0 组索引为00 行标记为1 偏移为0 在看上图的缓存组织情况可判读发生缓存不命中。于是从低一级存储中取出组索引为00 行标记为1 的数据也就是m[8]、m[9]放入第一行中然后返回m[8]操作后的缓存组织为通过上面的示例应该对缓存的工作原理有一定了解了把。其实就是吧地址分为不同的部分划分为表示组、行 和偏移。然后根据这些去判断所需地址是否在缓存中。如果在则返回数据不在则从低一级的存储中取出数据放入缓存中放入的位置由地址确定。然后返回地址。组相联高速缓存刚才讨论的直接映射高速缓存可以看作是缓存中的一个特例因为每组只有一行。这里介绍一下更普遍的缓存结构组相连高速缓存。其实就是每一组有多行。如下图是E 2 的缓存同样的当要从缓存中取地址为A的数据时1先确定地址A所在的组如下图所示

相关新闻