首页 > 编程语言 >【算法】页面替换算法

【算法】页面替换算法

时间:2023-05-02 20:33:57浏览次数:70  
标签:fr 请求 int 替换算法 访问 算法 缺页 页面

1  前言

功能:当缺页中断发生,需要调入新的页面而内存已满时,选择内存当中哪个物理页面被置换。

目标:尽可能地减少页面的换进换出次数(即缺页中断的次数)。具体来说,把未来不再使用的或短期内较少使用的页面换出,通常只能在局部原理指导下依据过去的统计数据来进行预测。

2  最优页面替换算法

基本思路:当一个缺页中断发生时,对于保存在内存当中的每一个逻辑页面,计算在它的下一次访问之前,还需等待多长时间,从中选择等待时间最长的那个作为被置换的页面。

这只是一种理想情况,在实际中无法实现,因为操作系统无法知道每一个页面要等待多长时间以后才会被再次访问。

可用作其它算法的性能评价的依据(在一个模拟器上运行某个程序,并记录每一次的页面访问情况,在第二遍运行时即可使用最优算法)。

简单一句话,最优页面替换算法就是替换在将来最长时间内不需要的页面

假设页帧(Page Frames)的大小为 4, 请求页面序列为:7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2,采用最优页面替换算法的缺页异常(Page Fault)的次数为多少?

初始时,页槽均为空,所以请求页面 7 0 1 2 被分配到空的页槽,产生 4 次缺页异常。

紧接着,请求页面 0 时,发现已经存在页帧中,0 次缺页异常;

当请求页面 3 时,页面 7 由于为在将来最长时间内不需要访问,所以被 3 替换,1 次缺页异常。

0 号页面命中,0 次页面异常;

请求页面 4 不存在页帧中,替换页面 1 ,1 次缺页异常;

对之后的请求页面序列 2,3,0,3,2 而言,均命中,固无缺页异常。

所以总共发生了 6 次缺页异常,即图中的 Miss 状态,其中的 Hit 表示命中,无缺页异常产生。 

模拟实现一个最优页面替换算法:

输入 : 页帧数 fn = 3  页面 pg[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1}; 

输出 : 命中次数 hits = 11 缺页异常 miss = 9

输入 : 页帧数 fn = 4  页面 pg[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2}; 

输出 : 命中次数 hits = 7 缺页异常 miss = 6

我们以页帧数 4 ,请求序列 {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2} 为例进行说明。

首先我们创建一个空的数组 fr 模拟页帧:

请求页面 7,发现不在数组 fr 当中且数组 fr 的大小 fr.size() < fn 页帧大小,则直接将请求页面 7 插入数组 fr中:

请求页面 {0,1,2} 与请求页面 7 情况类似,则依次将其添加到数组当中:

紧接着请求页面 0,遍历数组 fr ,发现 0 号页面已经在其中了,则命中次数 hit 加 1。

请求 3 号页面,遍历数组 fr ,发现不在其中且数组已满(fr.size == fn ),则需要找到要替换的页面,此时选择替换在将来最长时间内不需要的页面 。这里的将来最长时间不需要的页面,我们可以使用页面数组 pg[] 的下标进行表示。

遍历数组 fr[] ,并结合请求页面数组 pg[] 找到在将来最长时间内不需要的页面。

fr[0] = 7 ,我们从 3 号页面开始在数组 pg[] 中向后查找 7 号页面,发现其根本不存在,也就说 7 号页面就是在将来最长时间内不需要的页面。所以 3 号页面替换 7 号页面。

再访问 0 号页面,发现存在,则跳过;

访问 4 号页面,发现不在页帧数组 fr 当中,则替换掉在将来最长时间内不需要的页面 1:

之后访问页面 {2, 3, 0, 3, 2} 均为命中,总共命中 6 次。

参考实现:

#include <bits/stdc++.h>
using namespace std;

// 用于检查页帧中是否存在当前要访问的页 key
bool search(int key, vector<int>& fr)
{
     for (int i = 0; i < fr.size(); i++)
        if (fr[i] == key)
           return true;
     return false;
}

// 用于预测将来
int predict(int pg[], vector<int>& fr, int pn, int index)
{
    // 存储在将来最近要使用的页面的索引
    int res = -1, farthest = index;
    for (int i = 0; i < fr.size(); i++) {
        int j;
        for (j = index; j < pn; j++) {
           if (fr[i] == pg[j]) {
                if (j > farthest) {
                     farthest = j;
                     res = i;
                }
                break;
            }
        }

        // 如果某个页面将来从未被引用过,请将其返回。
        if (j == pn)
             return i;
     }
      // 如果 fr 中的所有页在将来都没出现过,则返回其中任何页,我们返回 0。否则我们将返回 res。
     return (res == -1) ? 0 : res;
}

/**
 * pg[] 请求页面序列
 * pn 请求页面数
 * fn 页帧数
 */
。
void optimalPage(int pg[], int pn, int fn)
{
    // 为给定数量的帧创建一个数组,并将其初始化为空。
   vector<int> fr;

   // 遍历页面引用数组并检查未命中和命中。
   int hit = 0;
   for (int i = 0; i < pn; i++) {
      // 在内存中命中页面 : HIT
      if (search(pg[i], fr)) {
         hit++;
         continue;
      }
      // 页面在内存中不存在 : MISS
      // 如果页帧中有可用的空间,则直接将缺失页加入其中。
      if (fr.size() < fn) {
           fr.push_back(pg[i]);
      }
      else { // 找到要替换的页
           int j = predict(pg, fr, pn, i + 1);
           fr[j] = pg[i];
        }
     }
     cout << "命中次数 = " << hit << endl;
     cout << "未命中次数 = " << pn - hit << endl;
}

int main()
{
     int pg[] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2 };
     int pn = sizeof(pg) / sizeof(pg[0]);
     int fn = 4;
     optimalPage(pg, pn, fn);
     return 0;
}

其中的 search 函数大家可以换成哈希或者二分查找等,其中最关键的是 predict() 函数,用于查找在将来最长时间内不会使用到的页面,其实也就是两层 for 循环嵌套。

3  先进先出算法

FIFO(First In,First Out)就是先进先出算法。

基本思路:选择在内存中驻留时间最长的页面并淘汰。具体来说,系统维护着一个链表,记录了所有位于内存当中的逻辑页面。从链表的排列顺序来看,链首页面的驻留时间最长,链尾页面的驻留时间最短。当发生一个缺页中断时,把链首页面淘汰出局,并把新的页面添加到链表的末尾。

性能较差,调出的页面可能是经常要访问的页面,并且产生 Belady 现象,FIFO 算法很少单独使用。

假设页帧(Page Frames)的大小为 4, 请求页面序列为:7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2,采用 FIFO 算法的缺页异常的次数为多少?

如上图所示,FIFO,先进先出,类似队列的特性。

对于请求页面 7,0,1,2 ,发生 4 次缺页中断,分别为其分配页;

访问页面 0 时,命中;

访问页面 3 时,缺页异常,此时会淘汰掉位于队列头的页面 7 ,将页面 3 插入到队尾,即选择在内存中驻留时间最长的页面并淘汰。

页面 0 命中;

访问页面 4 时,发生缺页异常,此时淘汰页面 0 ;

访问页面 2 和 3 时,均命中;

访问页面 0 时,缺页异常,淘汰页面 1 ,插入页面 0 ;

最后访问页面 3 和 2 均命中。

共发生缺页异常次数为 7 次。

4  时钟页面置换算法

Clock 页面置换算法,LRU 的近似,对 FIFO 的一种改进;

基本思路:

  • 需要用到页表顶当中的访问位(Access Bit),当一个页面被装入内存时,把该位初始化为 0。然后如果这个页面被访问(读写),则把该位置置为 1。
  • 把各个页面组织成环形链表(类似钟表面),把指针指向最老的页面(最先进来的页面);
  • 当发生一个缺页中断时,考察指针所指向的最老页面,若它的访问位为 0 ,立即淘汰;若访问位为 1,则把该位置置为 0,然后指针向下移动一格。如此下去,直到找到被淘汰的页面,然后把指针移动到它的下一格。

假设页帧(Page Frames)的大小为 4, 请求页面序列为:7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2,采用 时钟页面替换算法的缺页异常的次数为多少?

初始时,页帧为空,如下图所示的一个环形链表,是不是很想一个时钟:

请求页面 7,产生缺页中断,则将其装入内存,把该页面的访问位初始化为 0:

依次访问页面 0、1 和 2,与前面的方法类似:

紧接着请求页面 0 ,发现页面 0 已经在内存中了,则硬件会把访问位置为 1,并将指针下移:

请求页面 3 时,发生缺页中断,此时指针所指向的页面 7 的访问位为 0,则立即淘汰掉并替换为页面 3,访问位为 1:

请求页面 0,已存在内存中,硬件将其访问位置为 1,与上图一样,没有变化;

请求页面 4,发生缺页中断,首先将 3号页面的访问位置为 0, 0 号页面的访问位置为 0,指针下移,发现 1 号页面的访问位为0,则淘汰页面 1,替换为 4,访问位置 1 并下移指针:

请求页面 2 ,已存在内存中,硬件将其访问位置 1:

请求 3 号页面,将 3 号页面的访问位置为 1,将指针下移:

请求 0 号页面,将 0 号页面的访问位置 1,指针下移:

总的缺页中断次数为 5 次。

5  小结

其实就是怎么去选择元素进行淘汰哈,下节我们看下LRU、LFU,也是一种淘汰策略的算法,有理解不对的地方欢迎指正哈。

标签:fr,请求,int,替换算法,访问,算法,缺页,页面
From: https://www.cnblogs.com/kukuxjx/p/17368211.html

相关文章

  • 机器学习算法 随机森林学习 之决策树
    随机森林是基于集体智慧的一个机器学习算法,也是目前最好的机器学习算法之一。随机森林实际是一堆决策树的组合(正如其名,树多了就是森林了)。在用于分类一个新变量时,相关的检测数据提交给构建好的每个分类树。每个树给出一个分类结果,最终选择被最多的分类树支持的分类结果。回归则是不......
  • Stoer-Wagner 算法
    刚才可能是有用算法。这次是无用算法。无向图的最小割是最小的边集使得割掉后不连通。Stoer-Wagner算法可以在\(O(n^3)\)复杂度内解决无向图最小割。或者说实际上是\(O(nm\logm)\)。首先有一句废话:对于任意两点\(s,t\),割掉最小割后,或者处于一个连通块,或者处于不同的两个......
  • 06 ETH-挖矿算法
    《区块链技术与应用》课程链接:https://www.bilibili.com/video/BV1Vt411X7JF/?spm_id_from=333.337.search-card.all.click06ETH-挖矿算法目录06ETH-挖矿算法挖矿是保障区块链安全的一个重要手段。Blockchainissecuredbymining.bugbounty(悬赏找漏洞)比特币的挖矿算......
  • vue学习 第六天 浮动 (float) 和 页面传统布局(标准流、浮动、定位)。
    浮动(float)1、传统网页布局的三种方式(3种)网页布局的本质---用CSS来摆放盒子。把盒子摆放到相应位置。CSS提供了三种传统布局方式(盒子如何进行排列顺序):普通流(标准流)、浮动、定位2、标准流(普通流/文档流)就是标签按照规定好默认方式排......
  • 项目实践:我在嵌入式控制上对PID算法的理解
    关于PID算法的碎碎念(我也不知道咋说明)。笔者:czg-bky全文:我在嵌入式控制上对PID算法的理解-czg-bky-博客园(cnblogs.com)......
  • 6 年大厂面试官,谈谈我对算法岗面试的一些看法
    文|不敢透露姓名的Severus和小轶面试官坐在那撇着大嘴的,“咳,给你一机会,最短的时间内让我记住你。”这个我会,我抡圆了“啪!”,扭头我就走。我刚到家,录取通知书就来了,请你务必马上来一趟。——出自郭德纲的相声大家好,我是Severus,一个在某厂做中文文本理解的程序员。同时,也感谢小轶......
  • 分别使用SAD匹配,NCC匹配,SSD匹配三种算法提取双目图像的深度信息
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要       深度学习的蓬勃发展得益于大规模有标注的数据驱动,有监督学习(supervisedlearning)推动深度模型向着性能越来越高的方向发展。但是,大量的标注数据往往需要付出巨大的人力成本,越来......
  • 最近公共祖先 Tarjan算法
    例题:洛谷P3379【模板】最近公共祖先(LCA)https://www.luogu.com.cn/problem/P3379tarjan算法是利用了并查集来求LCA的,时间复杂度比倍增低,是O(n+m)#include<iostream>#include<vector>#include<utility>#defineforup(i,l,r)for(inti=l;i<=r;i++)#definefordown(i,l,r)fo......
  • 算法3:质数的个数
    一、质数的定义质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。二、判断质数的方法1for(intj=2;j<i;j++){2if(i%j==0)3break;4if(i==j)5cout<<i<<"";6}三、完整代码1#include<bits/stdc......
  • Mac M芯片使用PD安装centos7无页面安装
    1、选择Centos镜像点击继续设置虚拟机名称:点击创建:选择第一个回车开始下载系统,下载完成进入设置页面,首先输入1设置语言:进入语言设置,选择77普通话:选择c继续,又回到系统配置主页面:选择2进入设置时区页面设置时区:2:Asia 65:Shanghai选择c返回继续,5系统安装设置:......