高速缓存

  • 上次主要讲了磁盘如何访问,访问时间分为哪三部分,逻辑磁区号以及固态硬盘SSD。并引入了程序局部性原理、存储器层次结构和缓存思想。
  • 由于存储器相对CPU发展慢的多,因此计算机系统主要瓶颈是存储器性能瓶颈。我们通过建立存储器层次结构的解决方法,运用缓存思想、程序局部性原理(包括时间局部性和空间局部性)解决了这一问题
  • 下边我们讨论缓存的工作机制和高速缓存案例

缓存中读取数据的情况

  • 缓存工作机制:用小存储区域做高速缓存,CPU请求数据时先经过第k层,看第k层有没有这个数据,这层没有,再到下层查询。然后将数据块从下层加载到上一层,此时若此层已满,要牺牲此层的区域
命中(hit)
  • 命中即在第k层里有这个数据。值得一提的是,由于空间局部性的存在(访问此字节数据,其附近数据在将来可能被访问),我们在缓存数据时不是只缓存现在需要的这部分,而是将这部分附近的都要缓存进来。因此我们将存储的数据分成块,每次缓存时将一整块都缓存进来。
未命中(miss)
  • 未命中即请求数据在缓存块中没有,这时我们要一直往下层找,直到找到,然后把这一块数据放到缓存里,同时把请求的数据放到处理器中。这时就要考虑两个问题了,一个是映射,即我们把这块数据放到上层存储设备的哪一区域内;另一个是替换,即若上层已经满了,我们要牺牲那块原来的数据块来替换他。
  • 我们先来看替换,替换的基本原则是将未来一段时间内那块最不可能使用的换出去,我们设计了两种推理猜测算法
  1. LRU(rencently):将最后一次使用时间离现在最远的丢掉。
  2. LFU(fluently):在缓存块中放计数器,把使用次数最少的换出去。
  3. 瞎蒙:随机丢出去一个

值得注意的是,我们不推荐用人工智能、机器学习预测,这样可能准确性会更高,但是由于缓存需要短时间完成,而机器算法一算就是半天,不符合实际。由此看出替换算法不能太过复杂

缓存未命中分为三种情况
冷未命中 第一次尝试访问时,一定没有加载到缓存中,所以一定不会命中
冲突不命中 与替换策略有关,如有一种替换策略是第i列数据只能进入缓存的第i块。先让0进去,再让8进去时就要把0换出来,0再进去时又得把8换出来。由于缓存的储存结构导致频繁的换入换出
容量不命中 如果当前需要使用的热区非常大或者程序空间局部性特征非常差,会使频繁访问的块超过缓存的存储空间(缓存过小或者工作集过大)
  • 缓存不光存在于硬件中,软件如浏览器同样有缓存机制。第一次加载网页图片可能较慢,但不远后的未来再次加载就会很快,因为浏览器已经将这些图片存储到磁盘上。

设计缓存中需要考虑的问题

  • 缓存的数据实际上是内存中的哪一个位置的数据。cpu发的地址是内存地址,若要判断是否在缓存中存在,需要有东西在缓存块中记录这一缓存块的原始地址。
  • 数据块被缓存时,要缓存到缓存的哪个缓存块里
  • 写入缓存时的数据同步问题。写操作会改变数据,而在存储体系中,一个数据可能有多个副本存在,我们改数据时改动的是哪个数据;若没有全改,而导致产生数据不一致时,如何数据同步。对于数据同步策略,我们通常加一个标志位来表示数据是否被改动,若标志位被置位,要考虑数据同步。脏数据标志位,描述数据有没有被改动。

高速缓存算法

  • CPU芯片不只包含处理器,处理器只是一部分,负责做最终指令运算。高速缓存也在CPU芯片中,处理器中出来的数据,首先经过高速缓存,请求现有缓存解决,若能解决就先在CPU芯片内部解决,不发送到CPU外。未命中的再发到CPU芯片外
  • 值得注意的是,高速缓存的算法策略都是由硬件即电路来做,不是由软件完成,因此非常快。
  • 高速缓存_第1张图片

高速缓存的组织是一个二维结构,每个块是一个缓存的基本单位,假设有E个列,S个行,B是每个块能储存多少字节,都是2的整数次幂。缓存容量=E * S*B

  • 高速缓存_第2张图片每个块除了存储数据之外,还需要至少两个字节表示一些信息。valid bit表示缓存块是否缓存了数据;tag描述缓存块与内存哪一个区域建立了映射关系。
  • 而CPU在请求数据发来地址时,会把这个地址拆为组索引、块内偏移量、tag三个部分。收到地址后,先根据组索引,确定到缓存中哪个组查找;然后把这一组中所有块的tag与地址tag匹配,只有当valid bit为1且tag能匹配上时,才表示这个块命中;由于请求的数据往往只是块的一部分,还需要块内偏移量决定从块首偏移几个字节;最后由地址指向的的数据类型决定读取几个字节,完成最终读取。
  • 值得注意的是,组索引s和块内偏移量b位长都是S和B的二的整数幂的那个指数的位,这样恰好可以表示S和B中的每个数
直接映射高速缓存
  • 当E等于1,有S组,但是每组只有一个快,称为直接映射高速缓存。这样由组索引能直接确定块,再比对此块的tag和validbit 即可
  • 高速缓存_第3张图片

直接映射高速缓存的替换策略比较简单,这个进来那个出去;缺点是灵活性差,容易导致冲突未命中,导致性能下降

组相连高速缓存

高速缓存_第4张图片

  • 每组中有多个块,冲突未命中得到缓解,称为组相连高速缓存
  • 在相同缓存大小的情况下,增大E的值,每组中的块多了,冲突未命中得到缓解,提高性能;但是由于总容量不变,B也不便,E越高,势必导致分的组越少(S变少),甚至到到s=1,只有一组。
  • S=1的高速缓存称为全相连高速缓存,灵活度最高,只有一组,所有内存地址映射都到这组,每个块可以存储内存中的任意块。是最灵活的高速缓存,但是实现困难,需要所有块的tag同时做匹配,并行度非常高,会带来非常大的性能开销,减慢速度。全相连高速缓存空间上利用最好,但是时间上利用更多。这里又用到了trade-off来看待时间和空间,可以说计算机做任何设计时采用的思想都是中庸之道,不需要性能或者利用率有一个做到最高,而是找一个平衡点
  • 全相连高速缓存对于内存地址做解析时只需要分为两段,不需要组索引,因为只有一组

你可能感兴趣的:(计算机基础)