cache-replacement-policy-lru
Contents
Cache
cache
为啥要有 Cache
呢?根本原因是各种存储速度不匹配。或者为了加快某个过程,直接将多次转换的转换结果直接缓存起来,便于再次使用时直接绕开这些转换过程。典型的就是 MMU
的地址翻译过程,直接将虚拟地址
多次转换的最后结果,也就是物理地址
,直接缓存到 TLB
中,下次再次访问同一个虚拟地址,直接从虚拟地址拿到物理地址,绕开多次转换过程,这可不就提高了速度。CPU
的速度比 Memory
快得多,为了配上 CPU
超级快的速度,也就有了 L1
,L2
,L3
cache。还有就是存储器层次结构,速度快,容量小的存储作为速度慢,容量大的上级缓存。
cache replacement
为啥要有 cache replacement
呢? 因为再大的存储容量也有限,总有使用完的时候,何况速度快的存储,容量本身就小。cache 使用完,再有需要缓存的东西,就需要从缓存中剔除一些,来存放新的内容。那问题就来了,缓存使用完,该剔除哪些已经缓存的内容呢? 这就是所谓的 cache replacement policy
。从不同的角度,可以有不同的替换策略。
least recently used
本文来说明这个策略。我不想记忆定义。来通过一个实例来理解这个策略的思想。
磁盘要缓存到内存中的内容划分为相等的 page,称之为 virtual page
,每一个 page 一个编号,称之为 page number。
同理,内存的容量也划分为和磁盘大小一致的 page,称之为 page frame
。
以下为访问磁盘 page number 的顺序:
1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
缓存大小为 3 个 page frame。组成一个缓存 Queue
virtual page 存放规则
缓存队列没满
- virtual page 已在缓存队列中,将代表 virtual page 的队列节点移动到队首。
- virtual page 不在缓存队列中,添加代表这个 virtual page 的队列节点到队首。
缓存队列已满
- virtual page 已在缓存队列中,将代表 virtual page 的队列节点移动到队首。
- virtual page 不在缓存队列中,移除队尾队列节点,添加代表这个 virtual page 的队列节点到队首。
LRU 图解
可以看到一直是对缓存队列队首
操作。
1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
- 访问 page 1,缓存队列中没有,page 1 放到队首。
- 访问 page 2,缓存队列中没有,page 2 放到队首。
- 访问 page 3,缓存队列中没有,page 3 放到队首。
- 访问 page 4,缓存队列中没有,且缓存队列满了。移除队尾 page 1,page 4 放到队首。
- 访问 page 1,缓存队列中没有,且缓存队列满了。移除队尾 page 2,page 1 放到队首。
- 访问 page 2,缓存队列中没有,且缓存队列满了。移除队尾 page 3,page 2 放到队首。
- 访问 page 5,缓存队列中没有,且缓存队列满了。移除队尾 page 4,page 5 放到队首。
- 访问 page 1,缓存队列中有,page 1 移动到队首。
- 访问 page 2,缓存队列中有,page 2 移动到队首。
- 访问 page 3,缓存队列中没有,且缓存队列满了。移除队尾 page 5,page 3 放到队首。
- 访问 page 4,缓存队列中没有,且缓存队列满了。移除队尾 page 1,page 4 放到队首。
- 访问 page 5,缓存队列中没有,且缓存队列满了。移除队尾 page 2,page 5 放到队首。 最后缓存队列中存放的是 page 5,page 4,page 3。
由上可知从队首到队尾包含着一个信息就是,越接近队首,越是最近刚访问的 page。缓存背后的原理其实和
程序运行的局部性原理
有关。 通过上述操作,可以看到队列节点调整非常频繁,且队列节点之间有先后关系。这也决定了队列是个双端队列。 QNode 指针数组指向已经在缓存队列中的代表 page 的队列节点。
LRU 实现
|
|