文章目录
  1. 访问频率置换算法(FBR)
  2. LRU-K 2Q页置换算法
    1. LRU-K页置换算法
    2. LRU-2Q页置换算法
  3. LIRS页置换算法

访问频率置换算法(FBR)

操作系统维护一个如下形式的栈来存放缓存数据:

 

栈分为3个部分:新区域、中间区域与旧区域;每个缓存块都有一个引用计数,算法具体处理如下:

  • 访问的数据在栈中:缓存块被移到栈顶,若缓存块不在新区域,将其引用计数加1;
  • 访问的数据不在栈中:在访问完数据之后;栈的旧区域中引用计数最小的缓存块被移出;将访问的数据放到栈顶,其引用计数置1;

FBR算法的问题:需要调整参数。

LRU-K 2Q页置换算法

考虑一下在进程访问数据时,会有哪些模式的访问:

  • 顺序访问:数据块一个接一个被访问,不存在重复访问;
  • 循环访问:所有的数据块按照一定的间隔重复访问;
  • 时间密集访问:最近被访问的数据块是将来最可能被访问的;
  • 概率访问:所有数据块都有固定的概率被访问,且被访问的概率相互独立;

LRU-K页置换算法

LRU-K算法是LRU算法的扩展;增加了一个数据访问历史记录队列,记录数据被访问的次数以及最近的访问时间戳。

如果[数据]在离开历史记录队列之前被访问了K次,则需要将[数据]加入数据缓存队列:如果缓存队列的长度超过最大缓存长度,则先将缓存队列头部的数据删除,然后在缓存队列的队尾加上[数据],然后[数据]的访问历史记录从历史记录队列中删除。

若缓存队列的[数据]被访问,则将[数据]放到缓存队列的队尾。

综上,LRU-K页置换算法的示意图如下:

 

其中,LRU-2是综合考虑各种访问模式后的最优选择。

LRU-2Q页置换算法

进一步改进LRU-2页置换算法;使用两个缓存队列来维护缓存区,示意图如下:

 

数据块第一次被访问时,数据块缓存到FIFO队列的队尾(如果队列没有空闲空间,就删除队列头部的数据),如果数据块在离开FIFO队列之前被再次访问,则将数据块移到LRU队列的队尾(同样地,如果队列没有空闲空间,就删除队列头部的数据);若LRU队列的数据块被访问,则将数据块放到LRU队列的队尾。

LIRS页置换算法

定义两个属性;R(i,t):从最近一次访问数据块i之后到当前时刻t,被访问的不重复数据块数;IRR(i):在最近两次访问数据块i之间,被访问的不重复数据块数。

初始时,每个数据块的IRR=inf, R=0;

有数据块(记为i)被访问后,每个数据块的IRR值与R值更新:

  • 被访问:IRR(i,t)=R(i,t-1), R(i, t)=0;
  • 未被访问:IRR(j)不变,R(j,t)=R(j,t-1)+1{最近一次访问数据块j之后到t-1时刻, 数据块i没有被访问过},j!=i;

性质1:每次访问数据块时,除了被访问的数据块,其他数据块的R值均单调不减。

LIRS算法区分IRR值高的数据块与IRR值低的数据块,缓存区分为两个部分:常驻cache与暂驻cache;LIR块(低IRR值的数据块)放在常驻cache,HIR块(高IRR值的数据块)放在暂驻cache;

我们可以看到,R值其实就是IRR值的一个候选,一旦数据块被访问,它的R值就成为IRR值

由于常驻cache与暂驻cache是根据数据块的IRR值进行区分,那么这两个cache的数据块也会因为其IRR值进行调整;因此,当一个HIR块i被访问后,若存在LIR块j,R(j,t)>size且R(j,t)>IIR(i),则数据块i与数据块j的状态交换。即max{R(j,t)|j in LIR}>max{size, IIR(i)}。

LIRS算法在各种访问模式下均有很好的表现,但是算法要维护两组值(R值与IRR值)使得算法的开销很大;因此,也就有了下面利用栈而不用显式计算R值与IRR值的方法。

 

维护两个栈:栈S与栈Q;

栈S:LIR块(低IRR值的数据块)与IRR值小于LIR块的最大R值的HIR块(高IRR值的数据块);

栈Q:常驻cache中的HIR块;

事实上,栈S存放着当前的LIR块与之后有可能成为LIR块的HIR块;下面介绍”栈裁剪”操作。

“栈裁剪”操作:若栈S底部的LIR块被删除,则一直删除底部数据块直到遇到LIR块。

Q:”栈裁剪”操作的合理性是什么?

A:若栈S底部的LIR块被删除,则底部的HIR块将不会成为LIR块。

在证明”栈裁剪”操作的合理性之前,注意到如下的性质:

性质2:记S栈如下:

1
2
3
---------------------------------------
q_3 | q_2 | q_1 | q_0 |
---------------------------------------

那么R(q_i, t)>R(q_i+1, t),即R(q_i, t)>=R(q_i+1, t)+1。

对栈底部的HIR块i,考虑它再次被访问后:IRR(i)=R(i,t-1)>max{R(j,t-1)|j in LIR} => IRR(i)>=max{R(j,t)|j in LIR};从而状态交换的条件不成立,因此栈底部的HIR块不会成为LIR块;

考虑访问各种数据块时算法的反应:

1
2
3
4
5
6
7
8
|
|—— LIR块:LIR块移到栈顶,执行"栈裁剪"操作;
|
|—— HIR块
|
|—— 在S中:HIR块状态变为LIR并被移到S栈顶,S栈底LIR块状态变为HIR并从栈S中移到栈Q中,执行"栈裁剪"操作;
|
|—— 不在S中:HIR块移到Q栈顶;