赞
踩
首先,你需要了解E-ways组关联缓存的组织以及普通LRU替换算法。本文介绍一种,【近似】的LRU算法,它是借助一颗完全二叉树实现的。
考虑一个set中有n行的缓存(n-ways)。它们最近访问的时间有n!种组合(就是将它们按照最近访问时间排序)。比如3-ways的缓存,各行为ABC,就有ABC,ACB,BCA,BAC,CAB,CBA 6种。注意:我们不能简单地记录LRU的行,比如,CBAAB这个访问序列,我们需要记录(CAB)而不是(C),以便之后有新的访问后对该序列更新。显然,对每一个set我们需要O(log n!)=O(nlogn)位记录。
以4-ways 为例,一个set中有ABCD四行。
1)LRU的算法用一颗二叉树表示:
表示 | L2 | L1 | L0 | 替换 | L2 | L1 | L0 |
A | x | 1 | 1 | x | 0 | 0 | |
B | x | 0 | 1 | x | 1 | 0 | |
C | 1 | x | 0 | 0 | x | 1 | |
D | 0 | x | 0 | 1 | x | 1 |
①本来4-ways有24种排列,我们需要5位来维护,现在我们只用3位(L2,L1,L0)来维护。注意,我们不需要每一行都存这个二叉树。对于一个n-ways的缓存,不妨设n=2^t,二叉树需要t层,共有节点(2^t-1)个,也就是说我们只需要记录n-1位。
②如果最新访问了A行我们就按上表中【表示】来更新L2,L1,L0,x表示不更新。
③当我们要需要替换一行时,根据上表中【替换】来决定替换哪一行,比如,(1,1,0)表示替换B行。
④【替换】其实是【表示】取反。
具体的算法二叉树怎么画是随意的,比如你可以用L0=1表示AD,L0=0表示BC,只要这棵树没有逻辑错误就行。
2)实例:初始化(0,0,0),现在有一个访问序列ABCDACDAB,让我们来比较一下Pseudo LRU和LRU算法的结果。
(L2,L1,L0) | Pseudo LRU | LRU | ||
A | 011 | |||
B | 001 | |||
C | 100 | |||
D | 000 | A | A | √ |
A | 011 | C | B | C虽然不是最长时间未访问的,但是是“第二”最长时间未访问的 |
C | 110 | B | B | √ |
D | 010 | B | B | √ |
A | 011 | C | B | C虽然不是最长时间未访问的,但是是“第二”最长时间未访问的 |
B | 001 | C | C | √ |
3)总结来说,我们每次更新一些位数,而保留一些位数,使得任一时刻(L2,L1,L0)既包含着最新访问的信息,又包含着过去访问的信息。并且直观来说,因为【替换】是【表示】的取反,我们一定不会替换掉最新访问的行。所以,我们要么成功地替换了和严格LRU算法相同的行,要么替换了一个相对而言比较长时间没有用的行。考虑到LRU并不一定是最优的决定,Pserdo LRU在研究实验中整体而言表现优秀。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。