四路组相联原理_缓存工作原理

时间:2024-11-18 09:28:46

写在前面:本文是本人在调研研究方向时对存储器层次知识的复习记录,若对内容有疑问,可直接留言或邮件和我讨论。谢谢!

本文主要内容来源于《计算机体系结构 量化研究方法》

email: zhaos@

一. 一些概念:

缓存是指地址在离开处理器后遇到的第一级存储器层次结构。一般来说下,缓存是位于处理器和主存之间的存储器,材质为SRAM,其性能介于寄存器和主存DRAM之间。

从主存中提取固定大小的数据集并将其置于缓存中,这个数据集被称为

缓存对于存取的优化来源于局部性原理:对置于缓存中的某个块,时域局部性指出,可能最近一段时间还会被用到。空域局部性指出,马上用到这个块中其他数据的可能性也很高。

若处理器在缓存中找到了所需的数据项,则缓存命中,否则发生了缓存缺失。缓存缺失所需的时间取决于存储器介质的延迟和带宽,延迟决定了提取块中第一个数据项所需时延,带宽决定了提取块中其他数据项所需的时间。

由于在各级存取系统中利用局部性原理进行优化的情况非常普遍,因此只要使用了缓冲原理的结构,都可被泛称为缓存

如今缓存的概念已被扩充,不仅在CPU和主内存之间有Cache,而且在内存和硬盘之间也有Cache(磁盘缓存),乃至在硬盘与网络之间也有某种意义上的Cache──称为Internet临时文件夹或网络内容缓存等。凡是位于速度相差较大的两种硬件之间,用于协调两者数据传输速度差异的结构,均可称之为Cache。(来源:磁盘缓存和内存缓存的区别)

二. 缓存性能的评价:

缓存性能的优劣直接体现在缓存缺失率。缓存缺失由硬件处理,会导致按循环执行方式运行的处理器由于运算对象不可立即获取而发生暂停,这会阻塞后续指令的执行。即便是乱序执行的处理器,依然会导致需要使用该结果的指令等待,可能与前者相比,缺失代价较小。

CPU执行时间可表示为:

CPU执行时间 = (CPU指令执行周期数 + CPU停顿周期数) x 时钟周期时长

CPU停顿周期数可表示为:

CPU停顿周期数 = 缺失次数 x 缺失代价

=

此公式的优势在于分量比较好测量,IC为提交的指令数,缺失率为缺失次数除以访存次数,可以用缓存模拟器测量。

实际上,读出和写入的缺失率和缺失代价往往是不同的,写入的情况相对更加复杂。因此准确的来说应该分别计算再求和,合并来计算是一种简化。

三. 缓存组织方式

根据主存中的块在缓存中的映射方式不同,可把缓存组织方式分为三种。

直接映射:每个块只能出现在缓存中的固定位置。

全相联:每个块可出现在缓存中的任意位置。

组相联:把缓存分为若干(N)组,这些组由相同数量(M)的块构成。主存中的块只能出现在缓存中的固定组中,但可以位于组中任意位置。被称为M路组相联。

图1. 缓存组织方式,主存中块12在三种组织方式中的映射。(图片来源于《Computer Architecture 6th edition》)

直接映射可看作1路组相联,全相联可看作M路组相联

缓存中的块也可被称为cacheline,是对缓存和主存进行存取操作的最小粒度。

四. 缓存地址映射原理

直接映射和全相联可视作组相联的两种特殊情况,因此这里我们仅讨论组相联中主存地址的映射。

主存地址划分(如图2所示),首先划分为块地址块内偏移地址,再进一步把块地址划分为标志位组索引位

图2. 主存地址划分(图片来源于《Computer Architecture 6th edition》)

块地址确定映射到哪个缓存块:组索引位Index表示该主存数据项所在的块映射到固定的某一组,标志位通过比对确定该主存数据项所在的块映射到组中的某一缓存块。块内偏移地址确定映射到该缓存块的第几个缓存项。

图 缓存结构

图 主存地址结构 (图片来源于/qq_21125183/article/details/80590934)

由图可看出缓存块结构由三部分组成:有效位标志位数据部分。有效位表示当前缓存块是否包含有效地址,标志位与主存地址的标志位大小一致。

主存和缓存的映射可表述为:先通过主存的Index位来确定映射到缓存中的哪一组,在组中若存在标志位一致且有效位置位的缓存块,则说明缓存命中。在通过块内偏移地址确定具体映射到缓存块中的第几个缓存项。

地址映射中的一些等量关系,相关变量在图3中被列出:

五. 缓存缺失时的替换

当缓存缺失发生时,缓存控制器必须选择一个块位置被期望数据块替代。直接映射简化了替换的硬件判决,因为映射的位置是固定的,所以替换的位置也是固定的。而在全相联和组相联中,块的映射位置是任意的,因此替换时由多种选择。主要由三种策略。

随机替换

最近最少使用LRU

先入先出FIFO

三种方法的描述很浅显,在此省略。这里提一下,由于需要追踪记录的块很多,LRU的维护成本也很高,因此通常所使用的是一种近似的方法:伪LRU

六. 缓存写入策略

在处理器访问缓存,其大多数都是读取操作,通常来说处理器会等待读取操作的完成,这意味着要对读取操作进行优化。如在读取和比较标志位的同时取出缓存块,如果缓存命中,则直接把缓存块中所需部分传给处理器,若缺失,则直接忽略即可,仅增加一些功耗没有坏处。而在写入时,必须等到标志位校验成功才能写入,由于标志位校验不能并行执行,因此写入的时间通常大于读取。但对于写入的优化依然很重要。

通常情况下有两种写入策略。用来区分缓存方式。

直写(write through):数据将被写入缓存和低一级的存储器。

写回(write back):数据仅被写入缓存,当该缓存块发生替换时,再把数据写入低一级的存储器。为了减少写回块的频率,往往会对缓存块设置一个"脏(dirty)"位,缓存块若被修改,则称为脏数据,在发生替换时,若缓存块干净,则不需要写入主存。(某些处理器(如Opteron)缓存中脏块被“牺牲”,先会送到“牺牲缓冲区”,当缓存区满,缓存牺牲必须等待)。

两中方式各有优劣:

  1. 使用写回方式,写入速度与访问缓存的速度一致,且仅在替换时写入主存,多次修改仅需一次访问主存,使用的存储器带宽较少,节省功耗。
  2. 直写策略的实现更简单,且保证了存储器间数据一致性。这对多处理器和I/O非常重要。但是每次写入都需要对存储器进行写入,需要通过系统总线,会占用总线资源。
  3. 直写策略cpu在写入主存时会发生停顿,为了避免停顿,常用的优化方法时设置数据缓冲区,这个缓冲区位于缓存中,先把数据写入缓冲区,这样处理器可以继续执行之后的指令。

若写入时发生写入缺失,即写入的数据块不在缓存中。有以下两种方式处理:

写入分派(write allocate):与读取缺失处理方式相似,先把缺失的块读入缓存,再选择写入策略进行写入。

无写入分派(No-write allocate):直接写入主存,而跳过缓存。再这种方式中,只有读取操作会被缓存。

一般来说,写回策略与写入分派结合,希望对缺失块的后续操作可以被缓存所捕获。直写策略与无写入分派结合。

目前的处理器往往使用独立缓存:一个缓存专门用于指令缓存,另一个缓存专门用于数据缓存。处理器知到它是在发射一个指令地址还是一个数据地址,所以可能存在用于这两者的独立端口,从而使存储器层次结构和处理器之间的带宽加倍。