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

  • 不命中处罚(Miss Penalty):当缓存不命中时,要从下一层的存储结构中传输对应块到当前层中,需要额外的时间(不包含命中时间)。通常,贮存需要50~200个时钟周期。注意:命中和不命中两者对性能影响很大,比如99%命中率的性能会比97%命中率高两倍。
  • 接下来讨论高速缓存中不同参数对高速缓存性能的影响:
    参数优点缺点建议高速缓存大小越大提高命中率增加命中时间L1<L2<L3块大小越大利用程序的空间局部性,提高命中率1高速缓存固定式,块越大,行越少,无法利用局部性。2增加块传输时间现代系统块大小为64bits相联度越高降低高速缓存由于不命中导致的抖动1实现困难,成本高,速度慢 2需要更长标志位 3增加命中时间 4增加不命中处罚L1和L2使用8路组相联 L3使用16组相联
    想要编写高速缓存友好(Cache Friendly)的代码,基本方法为:
    • 让最常见的情况运行得快,将注意力集中在核心函数的循环中
    • 尽可能减少每个循环内部的缓存不命中,可以对局部变量反复引用,因为编译器会将其保存到寄存器中,其他的变量最好使用步长为1的引用模式。
    以CSAPP书中的练习题6.18为例探讨缓存命中和不命中的情况。
    首先根据题目可了解到,src数组和dest数组在内存中的存储方式为
    L1高速缓存的块大小为8字节,则b=3且一次存放两个int,而高速缓存大小为16个数据字节,说明高速缓存组为2组,则s=1。采用直接映射的、直写和写分配的高速缓存。一开始为空的,探讨以下代码的命中情况:

    储器层次结|「计算机组成原理」:高速缓存存储器
    文章插图
    第一轮:高速缓存为空,则对src[0][0]的读取会不命中,根据地址...00000可知,将其存放在组0中,且数据块保存了src[0][0]和src[1][1]。对dest[0][0]写时,根据其地址...10000可知会查看0组的位置,由于标志位不同,所以写不明中,会采用写分配,将对应的数据块保存到组0,其数据块包含dest[0][0]和dest[0][1],然后更新dest[0][0]。此时的高速缓存的内容为
    第二轮:读取src[0][1]时,根据其地址...00100可知,需要访问组0,由于标志位不同,所以读取不命中,会重新将src[0][0]和src[0][1]的数据块保存到0组中。对dest[1][0]写时,其地址为...11000,说明会访问组1,发现其中不包含任何数据,会出现写不命中,然后将包含dest[1][0]和dest[1][1]的数据块保存到组1中。
    第三轮:读取src[1][0]时,根据其地址...01000,需要访问组1,由于其标志位不同,所以读取不命中,会将包含src[1][0]和src[1][1]的数据块保存到组1中。对dest[0][1]写时,其地址为...10100,会访问组0,发现标志位不同,会出现写不命中,然后将dest[0][0]和dest[0][1]写入组0中。