《Cache Replacement Policies》一书介绍了硬件缓存设计中常用的缓存更新策略。虽然书中的介绍主要偏向硬件设计,但是对于软件开发也有一定参考价值,可以帮助我们更好理解常用的替换策略的运行机制。这里将我的一点感想分享出来,希望能够对大家有所帮助。如果对原作感兴趣,或者对本文的内容有疑问,有条件可以去阅读原文,此外,请注意成文时间,如果您很久以后才看到此文,可能文中所提内容将不在适用当下。
一、缓存替换策略的四个主要问题
- 插入规则(Insertion Policy):如何处理新来的Cache line?
- 晋升规则(Promotion Policy):如何处理命中的Cache line?
- 生长规则(Aging Policy):当有新的Cache line插入或者有Cache line命中时如何处理没有命中的那些Cache line?
- 淘汰规则(Eviction Policy):哪些Cache line将被淘汰?
这四个问题非常重要,后面讲的所有替换策略核心都是围绕这四个问题展开的。
二、分类
书中根据处理待缓存数据的方法,将替换策略分为粗粒度和细粒度两类。前者仅仅从时间或者频率上进行区分,关注使用行为,后者关注数据本身的特点,比如是否缓存友好,数据优先等级,数据之间的重用距离等等。
2.1 粗粒度
在粗粒度下,我们还可以分成根据调用时间,调用频率,或者两者混合动态决定的策略,如
- 基于上次使用时间分类,有:LRU、EELRU、SegLRU、LIP、Shepherd Cacge、SRRIP、BRRIP、PDP、GIPPR
- 基于使用频率分类,有:LFU、FBR、2Q、LFRU
- 混合型(动态决策型),有:ARC、DIP、DRRIP
2.2 细粒度
- 基于数据特征分类:DBCP、EAF、SDBP、SHiP、Hawkeye、MPPPB
- 基于重用距离分类:Timekeeping、AIP、ETA、Leeway
借用书中原图:
三、部分替换策略介绍
3.1 LRU(Least Recently Used)
LRU非常常见,如表中所示,LRU的核心思路就是维护一个从最近使用到最早使用的表,新插入的和命中的都放在最近使用的位置(即表头),其它Cache line向最早使用方向移动一位,缺页需要淘汰时,丢弃最早使用的那一个(即表尾)。
| 插入规则 | 晋升规则 | 生长规则 | 淘汰规则 |
|---|---|---|---|
| 表头 | 表头 | 向表尾移动一个位置 | 表尾 |
需要注意的是,对于CPU而言,当待用的数据集大于缓存大小的时候,命中率会变得非常低,缓存会频繁缺页,这种现象被称为抖动(threshold)。
对于抖动,书中有个例子:
缓存只有两个字大,待处理的数据为:A,B,C,A,B,C
按顺序访问数据时,缓存的情况如下表:
| 当前访问数据 | A | B | C | A | B | C |
|---|---|---|---|---|---|---|
| 缓存情况 | ||||||
| 说明 | 缺页 | 缺页 | 缺页,淘汰A | 缺页,淘汰B | 缺页,淘汰C | 缺页,淘汰A |
可以看到,全部请求都miss了。之后对LRU算法的改进,主要都集中在减少抖动,提高缓存命中率方面。
3.2 MRU(Most Recently Used)
针对LRU的抖动问题,将淘汰策略从LRU换成MRU,即淘汰表头。这可以有效提高工作进程需要的数据块超过了缓存的大小时的命中率
与LRU抖动同样的例子
| 当前访问数据 | A | B | C | A | B | C |
|---|---|---|---|---|---|---|
| 缓存情况 | ||||||
| 说明 | 缺页 | 缺页 | 缺页,淘汰B | 命中 | 缺页,淘汰C | 缺页,淘汰B |
可以看到,相较于LRU,MRU有一次命中
| 插入规则 | 晋升规则 | 生长规则 | 淘汰规则 |
|---|---|---|---|
| 表头 | 表头 | 向表尾移动一个位置 | 表头 |
虽然MRU相较于LRU提升了抖动下的性能,但是这个策略对于热点数据的访问非常不友好,性能很差。而且不会淘汰旧数据,在数据不停变更的情况下,缓存最终会被旧数据全部污染。
3.3 EELRU(Early Eviction LRU)
EELRU也可以避免抖动,它的主要机制是当发现工作数据大于缓存块的时候,随机选取靠近表尾的一些cache line淘汰,这样剩下的空间就可以较好的由LRU管理起来。借用书中的图可以很直观的理解这句话:
- l为原点,MRU,或者是链表的表头
- e为随机选择的提前淘汰位置
- M表示缓存的空间
- 发生缺页时,缓存将从early region或者late region淘汰cache line
| 插入规则 | 晋升规则 | 生长规则 | 淘汰规则 |
|---|---|---|---|
| 表头 | 表头 | 向表尾移动一个位置 | 表尾或者第e个之后的位置 |
具体说来,该策略需要追踪每个region中命中的次数,如果分布单调递减,则假设没有发生抖动,正常淘汰表尾,如果分布表现出late区域命中高于early区域,则从early区域淘汰。
3.4 SRRIP(Static Re-Reference Interval Prediction)
(待补)
3.5 PDP(Protecting Distance-Based Policy)
(待补)
3.6 LFU(Least Frequently Used)
(待补)
3.7 LRFU(Least Recently/Frequently Used)
(待补)
3.8 ARC(ADAPTIVE REPLACEMENT CACHE)
(待补)
3.9 DIP(Dynamic Insertion Policy)
(待补)
3.10 DRRIP(Dynamic Re-Reference Interval Policy)
(待补)