Skip to content

Cache之我见

对于cache,大家都很了解,但又似乎不完全了解。在从事微架构相关的工作之前,我对cache的了解很局限,只能说出一些表面的东西;在接触微架构之后,才逐渐的对cache有更深的理解。

本文主要目的是记录自己对cache的理解,因此不会再系统的对cache进行描述,会显得干涩,缺少图片,建议结合宝华的cache系列讲解一同观看。

cache结构

从理论上来讲,cache可以分为如下三种

  • 直接映射(单路组相连)cache
  • 多路组相连cache
  • 全相连cache

不同的cache结构会有不同的地址划分方案。也可以认为是编码方案。(这种思想在CPU架构中经常使用,比如MMU查找页表的过程也是 对地址进行了划分)但都划分为tag,index,offset这几个区域

直接映射cache

直接映射cache是最简单的,它应该是cache设计的第一个版本。有它没它肯定区别比较大。 那么在查找cache的时候,首先匹配index,找到对应的cacheline,然后匹配tag,校验标志位,确认是否命中,如果命中,则根据offset在cacheline中找到具体的数据,不命中就需要去下一级内存中进行查找了。

对于直接映射缓存,一旦不命中,当前index对应的cacheline就会被换出。但实际上,有可能被换出的cacheline也会在不久之后就被用到,这就发生了cache颠簸,大大降低了效率。根本原因还是因为操作地址中的index与tag是一对一的关系,相同的index的不同tag的地址也有可能会满足局部性,但对于直接映射cache,它只能存一个tag。

多路组相连cache

为了解决cache颠簸的问题,这里就引入了多路组相连的设计。核心思想是,index锁定的是cacheline组,每一个组员都有它自己的tag,这样就不会因为index一致而必须换出某一个cacheline。这样在理论上要比直接映射好,多路组相连的最坏情况也不过是跟直接映射一样,每次都换出。

这里就引入了一个策略问题,一旦整个组都miss,如何决定换哪一个的问题。

全相连cache

全相连是一种极端情况,只有一个组,可以根据策略来决定到底换哪一个。当然,在物理上这也是最复杂的。多路组相连的一种兼顾方案。

cache工作流程

查找过程

替换过程

flush过程

cache一致性