(计算机组成原理)第三章存储系统-第六节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中,所以前四次都是调入的过程,也就不会发生替换

访问主存块123412512345
Cache #01111
Cache #1222
Cache #233
Cache #34
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},由于1,2主存块已经被调入了Cache,因此直接命中

访问主存块123412512345
Cache #0111111
Cache #122222
Cache #23333
Cache #3444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。对于5号主存块,Cache里并没有调入它 ,因此需要立即被调入,但是调入时Cache已经满了,且这里采用的是随机算法,所以我们可以任意挑选一块调入
比如把3号主存块给替换出去

访问主存块123412512345
Cache #01111111
Cache #1222222
Cache #233335
Cache #34444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},命中

访问主存块123412512345
Cache #0111111111
Cache #122222222
Cache #23333555
Cache #3444444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},采用随机替换

访问主存块123412512345
Cache #01111111111
Cache #1222222222
Cache #233335555
Cache #34444443
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},采用随机替换

访问主存块123412512345
Cache #011111111114
Cache #12222222222
Cache #2333355555
Cache #344444433
是否命中?
是否替换?

最后结束这个过程,也即{1,2,3,4,1,2,5,1,2,3,4,5},命中

访问主存块123412512345
Cache #0111111111144
Cache #122222222222
Cache #23333555555
Cache #3444444333
是否命中?
是否替换?

因此随机算法十分简单,但是它完全没有考虑到局部性原理,命中率很低,实际效果很不稳定

二:先进先出算法(FIFO)

先进先出算法正如它的名字:若Cache已满,则替换最先被调入Cache的块
仍然采用之前的例子,直接到这一步

访问主存块123412512345
Cache #0111111
Cache #122222
Cache #23333
Cache #3444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。此时,对于5号主存块,它需要被调入Cache,根据先进先出原则,最先被调入Cache的最先被替换,因此1号被替换

访问主存块123412512345
Cache #01111115
Cache #1222222
Cache #233333
Cache #34444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},此时应该替换2号

访问主存块123412512345
Cache #011111155
Cache #12222221
Cache #2333333
Cache #344444
是否命中?
是否替换?

后续步骤不再详细演示,最终结束状态如下

访问主存块123412512345
Cache #0111111555544
Cache #122222211115
Cache #23333332222
Cache #3444444333
是否命中?
是否替换?

所以,先进先出算法实现也很简单,在开始时按照#0#1#2#3的顺序放入Cache,之后仍然可以按照此顺序轮流替换。该算法依然没有考虑到局部性原理,因为最先被调入的Cache块也有可能是会频繁访问到的

另外该算法也会更容易产生抖动现象——刚换上去的块又立马被换下

三:近期最少使用算法(LRU)——效率最高

LRU算法是指:会为每一个Cache块设置一个“计数器”,用于记录每个Cache块究竟有多长时间没有被访问了。在替换时直接选取“计数器”最大的替换即可

还是采用之前的例子,大家可以发现相比之前的算法,这里多了一个计时器选项
计数器的变化规则如下

  • 命中时,所命中的行的计数器清零,比其低的计数器+1,其余不变
  • 未命中且还有空闲行时,新装入的行的计数器置为0,其余非空闲行全+1
  • 未命中且没有空闲行时,计数器最大的行的信息块被淘汰,新装入行的计数器置为0,其余全+1
计时器访问主存块123412512345
0Cache #0
0Cache #1
0Cache #2
0Cache #3
是否命中?
是否替换?

首先,来到第一个主存块1,也即{1,2,3,4,1,2,5,1,2,3,4,5}。由于1装入了第一个Cache块,属于未命中且是空闲行,因此该空闲行置为0,其余非空闲行全+1

计时器访问主存块123412512345
0Cache #01
0Cache #1
0Cache #2
0Cache #3
是否命中?
是否替换?

接着到第二个主存块2,也即{1,2,3,4,1,2,5,1,2,3,4,5},同上面

计时器访问主存块123412512345
1Cache #011
0Cache #12
0Cache #2
0Cache #3
是否命中?
是否替换?

第三、四个主存块亦是如此

计时器访问主存块123412512345
3Cache #01111
2Cache #1222
1Cache #233
0Cache #34
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。此时Cache命中,因此需要将所命中的行的计数器清零,比其低的计数器+1,其余不变,这一点其实就体现了LRU算法的核心,它能保证最近访问的块的计数器一定很低

计时器访问主存块123412512345
0Cache #011111
3Cache #12222
2Cache #2333
1Cache #344
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。

计时器访问主存块123412512345
1Cache #0111111
0Cache #122222
3Cache #23333
2Cache #3444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}。第5块主存块需要进行替换,此时属于 “未命中且没有空闲行时,计数器最大的行的信息块被淘汰,新装入行的计数器置为0,其余全+1”这种情况

计时器访问主存块123412512345
2Cache #01111111
1Cache #1222222
0Cache #233335
3Cache #34444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},可以命中。需要注意的是只需要将“比该行计数器值小的+1”即可,大的不变,因此上面表格中的3号Cache的计时器就不用动了

计时器访问主存块123412512345
0Cache #011111111
2Cache #12222222
1Cache #2333355
3Cache #344444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},可以命中。

计时器访问主存块123412512345
1Cache #0111111111
0Cache #122222222
2Cache #23333555
3Cache #3444444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},未命中,且没有空行

计时器访问主存块123412512345
2Cache #01111111111
1Cache #1222222222
3Cache #233335555
0Cache #34444443
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},未命中,且没有空行

计时器访问主存块123412512345
3Cache #011111111111
2Cache #12222222222
0Cache #2333355554
1Cache #344444433
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},未命中,且没有空行

计时器访问主存块123412512345
0Cache #0111111111115
3Cache #122222222222
1Cache #23333555544
2Cache #3444444333
是否命中?
是否替换?

可以发现,LRU算法中,Cache块的总块数= 2 n 2^{n} 2n,则计数器只需要n位。比如这里是4块,那么计数器只会在0到3变化

LRU算法是基于局部性原理的,近期访问过的主存块,在不久的将来很有可能会被再次访问到,因此这种淘汰机制是合理的。LRU算法的实际运行效果也很优秀,Cache命中率也高

四:最不经常使用算法(LFU)

LFU算法会为每一个Cache块设置一个计数器,用于记录每个Cache块被访问过几次,当Cache块满后会替换计数器最小的

计数器的变化规则为:

  • 新调入的块计数器为0,之后每访问一次计数器就+1。需要替换时,选择计数器最小的一行替换
  • 若有多个计数器最小的行,可以按照行号递增或FIFO策略进行选择
计时器访问主存块123412512345
0Cache #0
0Cache #1
0Cache #2
0Cache #3
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5}

计时器访问主存块123412512345
0Cache #01111
0Cache #1222
0Cache #233
0Cache #34
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},发生命中,计数器+1

计时器访问主存块123412512345
1Cache #0111111
1Cache #122222
0Cache #23333
0Cache #3444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},对于5号需要进行替换,选择计数器最小的那一行,但是这里有两行相同,这里按照FIFO策略选择3号主存块淘汰

计时器访问主存块123412512345
1Cache #01111111
1Cache #1222222
0Cache #233335
0Cache #34444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},1,2可以命中,计数器+1

计时器访问主存块123412512345
2Cache #0111111111
2Cache #122222222
0Cache #23333555
0Cache #3444444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},需要进行替换,这里我们再采用行号递增的规则淘汰5号主存块

计时器访问主存块123412512345
2Cache #01111111111
2Cache #1222222222
0Cache #233335553
0Cache #34444444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},可以命中,计时器+1

计时器访问主存块123412512345
2Cache #011111111111
2Cache #12222222222
0Cache #2333355533
1Cache #344444444
是否命中?
是否替换?

接着继续进行,也即{1,2,3,4,1,2,5,1,2,3,4,5},需要替换,只剩一个最小的了,替换它3号主存块即可

计时器访问主存块123412512345
2Cache #0111111111111
2Cache #122222222222
0Cache #23333555335
1Cache #3444444444
是否命中?
是否替换?

LFU算法并没有很好地遵循局部性原理,比如微信聊天相关的块,在某个时间段内使用率会很高,但是一段时间后使用率会很低,并不科学。

以上是关于(计算机组成原理)第三章存储系统-第六节3:页面置换算法(FIFO,近期最少使用算法-LRU,LFU)的主要内容,如果未能解决你的问题,请参考以下文章

(计算机组成原理)第三章存储系统-第六节4:Cache的写策略(写回法和全写法,写分配法和非写分配法)

(计算机组成原理)第三章存储系统-第六节2:Cache和主存的映射方式(全相联映射直接映射和组相连映射)

(王道408考研操作系统)第三章内存管理-第二节3:页面置换算法1

(王道408考研操作系统)第三章内存管理-第二节2:页面置换算法1

网络层-第六节3:开放最短路径优先OSPF的基本工作原理

网络层-第六节4:边界网关协议BGP的基本工作原理