(计算机组成原理)第三章存储系统-第六节3:页面置换算法(FIFO,近期最少使用算法-LRU,LFU)
Posted 快乐江湖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(计算机组成原理)第三章存储系统-第六节3:页面置换算法(FIFO,近期最少使用算法-LRU,LFU)相关的知识,希望对你有一定的参考价值。
(计算机组成原理)第三章存储系统-第六节2:Cache和主存的映射方式(全相联映射、直接映射和组相连映射)中我们讲到了Cache和主存之间的映射关系,细致分析了三种映射方式各自的特点。那么下一个亟待解决的问题就是:Cache是很小的,主存却很大,如果Cache满了应该怎么办? 这也就是本节的主题——Cache的替换算法。需要注意的时不同映射方式其替换机制不同
- 全相联映射:Cache完全满了才需要替换,需要在全局中选择替换哪一块
- 直接映射:如果对应位置为空则直接替换,无序考虑替换算法
- 组相联映射:分组内完了才需要替换,需要在分组内选择替换哪一块
那么本小节就以全相联映射为例,介绍以下四种替换算法
- 随机算法(RAND)
- 先进先出算法(FIFO)
- 近期最少使用算法(LRU)
- 最近不经常使用(LFU)
在讲解之前大家一定明白一点,CPU每访问一个内存块,都会立即把该内存块调入Cache中
一:随机算法(RAND)
随机算法就是指:若Cache已满,则随机选择一块进行替换
如下,有4个Cache块,初始状态整个Cache为空,采用全相连映射。CPU依次访问主存块的顺序为:{1,2,3,4,1,2,5,1,2,3,4,5},由于每访问一个内存块,都会立即把该内存块调入Cache中,所以前四次都是调入的过程,也就不会发生替换
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | ||||||||
Cache #1 | 2 | 2 | 2 | |||||||||
Cache #2 | 3 | 3 | ||||||||||
Cache #3 | 4 | |||||||||||
是否命中? | 否 | 否 | 否 | 否 | ||||||||
是否替换? | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},由于1,2主存块已经被调入了Cache,因此直接命中
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | ||||||
Cache #1 | 2 | 2 | 2 | 2 | 2 | |||||||
Cache #2 | 3 | 3 | 3 | 3 | ||||||||
Cache #3 | 4 | 4 | 4 | |||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | ||||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。对于5号主存块,Cache里并没有调入它 ,因此需要立即被调入,但是调入时Cache已经满了,且这里采用的是随机算法,所以我们可以任意挑选一块调入
比如把3号主存块给替换出去
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||||
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | ||||||
Cache #2 | 3 | 3 | 3 | 3 | 5 | |||||||
Cache #3 | 4 | 4 | 4 | 4 | ||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | |||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},命中
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ||||
Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | |||||
Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | ||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | |||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},采用随机替换
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | ||
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |||
Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 | ||||
Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | |||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | ||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},采用随机替换
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 4 | |
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ||
Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 | 5 | |||
Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | ||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | 否 | |
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 | 是 |
最后结束这个过程,也即{1,2,3,4,1,2,5,1,2,3,4,5},命中
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 4 | 4 |
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |
Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 | 5 | 5 | ||
Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | 3 | |||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | 否 | 是 |
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 | 是 | 否 |
因此随机算法十分简单,但是它完全没有考虑到局部性原理,命中率很低,实际效果很不稳定
二:先进先出算法(FIFO)
先进先出算法正如它的名字:若Cache已满,则替换最先被调入Cache的块
仍然采用之前的例子,直接到这一步
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | ||||||
Cache #1 | 2 | 2 | 2 | 2 | 2 | |||||||
Cache #2 | 3 | 3 | 3 | 3 | ||||||||
Cache #3 | 4 | 4 | 4 | |||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | ||||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。此时,对于5号主存块,它需要被调入Cache,根据先进先出原则,最先被调入Cache的最先被替换,因此1号被替换
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 5 | |||||
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | ||||||
Cache #2 | 3 | 3 | 3 | 3 | 3 | |||||||
Cache #3 | 4 | 4 | 4 | 4 | ||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | |||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},此时应该替换2号
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 5 | 5 | ||||
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 1 | |||||
Cache #2 | 3 | 3 | 3 | 3 | 3 | 3 | ||||||
Cache #3 | 4 | 4 | 4 | 4 | 4 | |||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 否 | ||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 是 |
后续步骤不再详细演示,最终结束状态如下
访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 5 | 5 | 5 | 5 | 4 | 4 |
Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 5 | |
Cache #2 | 3 | 3 | 3 | 3 | 3 | 3 | 2 | 2 | 2 | 2 | ||
Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | 3 | |||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 是 | 是 | 是 | 是 | 是 |
所以,先进先出算法实现也很简单,在开始时按照#0#1#2#3的顺序放入Cache,之后仍然可以按照此顺序轮流替换。该算法依然没有考虑到局部性原理,因为最先被调入的Cache块也有可能是会频繁访问到的
另外该算法也会更容易产生抖动现象——刚换上去的块又立马被换下
三:近期最少使用算法(LRU)——效率最高
LRU算法是指:会为每一个Cache块设置一个“计数器
”,用于记录每个Cache块究竟有多长时间没有被访问了。在替换时直接选取“计数器
”最大的替换即可
还是采用之前的例子,大家可以发现相比之前的算法,这里多了一个计时器选项
计数器的变化规则如下
- 命中时,所命中的行的计数器清零,比其低的计数器+1,其余不变
- 未命中且还有空闲行时,新装入的行的计数器置为0,其余非空闲行全+1
- 未命中且没有空闲行时,计数器最大的行的信息块被淘汰,新装入行的计数器置为0,其余全+1
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | ||||||||||||
0 | Cache #1 | ||||||||||||
0 | Cache #2 | ||||||||||||
0 | Cache #3 | ||||||||||||
是否命中? | |||||||||||||
是否替换? |
首先,来到第一个主存块1,也即{1,2,3,4,1,2,5,1,2,3,4,5}。由于1装入了第一个Cache块,属于未命中且是空闲行,因此该空闲行置为0,其余非空闲行全+1
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | 1 | |||||||||||
0 | Cache #1 | ||||||||||||
0 | Cache #2 | ||||||||||||
0 | Cache #3 | ||||||||||||
是否命中? | 否 | ||||||||||||
是否替换? | 否 |
接着到第二个主存块2,也即{1,2,3,4,1,2,5,1,2,3,4,5},同上面
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Cache #0 | 1 | 1 | ||||||||||
0 | Cache #1 | 2 | |||||||||||
0 | Cache #2 | ||||||||||||
0 | Cache #3 | ||||||||||||
是否命中? | 否 | 否 | |||||||||||
是否替换? | 否 | 否 |
第三、四个主存块亦是如此
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3 | Cache #0 | 1 | 1 | 1 | 1 | ||||||||
2 | Cache #1 | 2 | 2 | 2 | |||||||||
1 | Cache #2 | 3 | 3 | ||||||||||
0 | Cache #3 | 4 | |||||||||||
是否命中? | 否 | 否 | 否 | 否 | |||||||||
是否替换? | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。此时Cache命中,因此需要将所命中的行的计数器清零,比其低的计数器+1,其余不变,这一点其实就体现了LRU算法的核心,它能保证最近访问的块的计数器一定很低
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | 1 | 1 | 1 | 1 | 1 | |||||||
3 | Cache #1 | 2 | 2 | 2 | 2 | ||||||||
2 | Cache #2 | 3 | 3 | 3 | |||||||||
1 | Cache #3 | 4 | 4 | ||||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | ||||||||
是否替换? | 否 | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | ||||||
0 | Cache #1 | 2 | 2 | 2 | 2 | 2 | |||||||
3 | Cache #2 | 3 | 3 | 3 | 3 | ||||||||
2 | Cache #3 | 4 | 4 | 4 | |||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | |||||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。第5块主存块需要进行替换,此时属于 “未命中且没有空闲行时,计数器最大的行的信息块被淘汰,新装入行的计数器置为0,其余全+1”这种情况
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||||
1 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | ||||||
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | |||||||
3 | Cache #3 | 4 | 4 | 4 | 4 | ||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | ||||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},可以命中。需要注意的是只需要将“比该行计数器值小的+1”即可,大的不变,因此上面表格中的3号Cache的计时器就不用动了
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | ||||
2 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |||||
1 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | ||||||
3 | Cache #3 | 4 | 4 | 4 | 4 | 4 | |||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | |||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},可以命中。
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||
0 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ||||
2 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | |||||
3 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | ||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | ||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},未命中,且没有空行
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | ||
1 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |||
3 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 | ||||
0 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | |||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | |||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},未命中,且没有空行
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |
2 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ||
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 | 4 | |||
1 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | ||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | 否 | ||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},未命中,且没有空行
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 5 |
3 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |
1 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 | 4 | 4 | ||
2 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | 3 | |||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | 否 | 否 | |
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 | 是 | 是 |
可以发现,LRU算法中,Cache块的总块数= 2 n 2^{n} 2n,则计数器只需要n位。比如这里是4块,那么计数器只会在0到3变化
LRU算法是基于局部性原理的,近期访问过的主存块,在不久的将来很有可能会被再次访问到,因此这种淘汰机制是合理的。LRU算法的实际运行效果也很优秀,Cache命中率也高
四:最不经常使用算法(LFU)
LFU算法会为每一个Cache块设置一个计数器,用于记录每个Cache块被访问过几次,当Cache块满后会替换计数器最小的
计数器的变化规则为:
- 新调入的块计数器为0,之后每访问一次计数器就+1。需要替换时,选择计数器最小的一行替换
- 若有多个计数器最小的行,可以按照行号递增或FIFO策略进行选择
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | ||||||||||||
0 | Cache #1 | ||||||||||||
0 | Cache #2 | ||||||||||||
0 | Cache #3 | ||||||||||||
是否命中? | |||||||||||||
是否替换? |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Cache #0 | 1 | 1 | 1 | 1 | ||||||||
0 | Cache #1 | 2 | 2 | 2 | |||||||||
0 | Cache #2 | 3 | 3 | ||||||||||
0 | Cache #3 | 4 | |||||||||||
是否命中? | 否 | 否 | 否 | 否 | |||||||||
是否替换? | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},发生命中,计数器+1
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | ||||||
1 | Cache #1 | 2 | 2 | 2 | 2 | 2 | |||||||
0 | Cache #2 | 3 | 3 | 3 | 3 | ||||||||
0 | Cache #3 | 4 | 4 | 4 | |||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | |||||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},对于5号需要进行替换,选择计数器最小的那一行,但是这里有两行相同,这里按照FIFO策略选择3号主存块淘汰
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||||
1 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | ||||||
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | |||||||
0 | Cache #3 | 4 | 4 | 4 | 4 | ||||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | ||||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},1,2可以命中,计数器+1
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||
2 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ||||
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | |||||
0 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | ||||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | ||||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},需要进行替换,这里我们再采用行号递增的规则淘汰5号主存块
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | ||
2 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |||
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 3 | ||||
0 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | |||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | |||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},可以命中,计时器+1
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |
2 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ||
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 3 | 3 | |||
1 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | ||||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | 是 | ||
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 | 否 |
接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},需要替换,只剩一个最小的了,替换它3号主存块即可
计时器 | 访问主存块 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | Cache #0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | Cache #1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | |
0 | Cache #2 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 3 | 3 | 5 | ||
1 | Cache #3 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | |||
是否命中? | 否 | 否 | 否 | 否 | 是 | 是 | 否 | 是 | 是 | 否 | 是 | 否 | |
是否替换? | 否 | 否 | 否 | 否 | 否 | 否 | 是 | 否 | 否 | 是 | 否 | 是 |
LFU算法并没有很好地遵循局部性原理,比如微信聊天相关的块,在某个时间段内使用率会很高,但是一段时间后使用率会很低,并不科学。
以上是关于(计算机组成原理)第三章存储系统-第六节3:页面置换算法(FIFO,近期最少使用算法-LRU,LFU)的主要内容,如果未能解决你的问题,请参考以下文章
(计算机组成原理)第三章存储系统-第六节4:Cache的写策略(写回法和全写法,写分配法和非写分配法)
(计算机组成原理)第三章存储系统-第六节2:Cache和主存的映射方式(全相联映射直接映射和组相连映射)
(王道408考研操作系统)第三章内存管理-第二节3:页面置换算法1