页面置换算法之FIFO、LRU、OPT和Clock算法及其实现

本文介绍页面置换算法FIFO、LRU、OPT和Clock及其实现。页面置换完成逻辑与物理内存分离,针对页码调入的三种情况设计了这四种算法。FIFO用队列管理页面;OPT置换最长时间不使用的页面;LRU需更新队列元素;Clock通过visit数组实现第二次访问。

页面置换算法之FIFO、LRU、OPT和Clock算法及其实现

页面置换

页面置换:页面置换是请求调页的基础,它完成了逻辑内存和物理内存之间的分离,采用这种机制,较小的物理内存能为程序员提供巨大的虚拟内存。

在页码被调入的时候,会有三种情况发生:
a. 类似初始化状态,内存未满,但是没有该页码,需要从磁盘中直接引入。
b. 内存已满,产生缺页错误,需要请求调页。
c. 内存已满,但是存在改页码,可以直接使用,不需要调页,也不会产生缺页错误。

所以针对这三种情况,设计如下四种页面置换算法:

FIFO页面置换

FIFO 是最简单的页面置换算法,它为每一个页面记录了调到内存的时间,当必须置换页面时,将选择最旧的页面。具体实现的话,我们并不需要记录调入页面的具体时间,只需要创建一个FIFO队列,来管理所有的内存页面,置换的是队列的首个页面,当需要调入页面到内存时,就将它加入到队列的尾部。

OPT页面置换

这个算法具有所有算法的最低的缺页错误率。并且不会遭受Belady异常,被称为OPT或者MIN。
OPT为置换最长时间不使用的页面,他与LRU算法不同的是需要向后看,寻找最不经常使用的页码,所以我们只需要向后看,有两种情况则可以结束前进:

  1. 找到了(最大帧数-1)个页码号,则剩下的那一个页码即为我们要替换的页码
  2. 找到了最后,都没有找到(最大帧数-1)个页码,这就按FIFO算法将没有找到的页码踢掉。

LRU页面置换

同为采用队列实现,LRU与FIFO不同的地方,需要更新不断出现的元素,将它重新插入一遍,所以对应于上面的三种情况中的c,这时所需要的页码在内存中已经存在,不能只是简单的直接调用进程,还需要将该页码更新一下,以证明最近使用过(找到页码所对应的位置,将它在队列中删掉,重新插入一遍)。

Clock算法

Clock又叫第二次机会算法,通过一个visit数组来实现第二次访问,利用循环队列相应的知识,在FIFO的基础上,在开辟一个与之对应的数组,其索引必须相呼应,两者具体关系如下:
a. 页码刚被调入,设置其页码对应的visit为1;
b. 访问过一次,则将其visit设置为0;
c. 页码被替换,对应的visit也要更新为1。
总之,将visit与队列实现同步操作即可。

具体代码如下:

#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
#include<time.h>

using namespace std;

#define N 20    //Page_Name
#define M 3     //Frame_Max_name

int in(vector<int> map,int num){             //判断新进来的元素是否已经存在与内存里面
    int flag = 0; 
    vector<int>::iterator v = map.begin();
    while( v != map.end()) {
        if(num == *v){
            flag = 1;
            break;
        }
        v++;
    }
    return flag;
}

int return_index(vector<int> map,int num){     //因为栈、队列等数据结构没有遍历的功能,所以写这个函数来直接定位某个元素的索引
    int index = 0;
    vector<int>::iterator v = map.begin();
    while( v != map.end()) {
        if(num == *v){
            break;
        }
        v++;
        index++;
    }
    return index;
}
int main(){
    int arr[N];//= {7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};
    vector<int> map;   //判断是否在stack or queue中
    int num = 0;       //缺页数
    int num1,num2,num3,num4,num5;
    srand((unsigned int)(time(NULL)));
    for(int i=0;i<N;i++){ //随机生成arr数组 表示接下来要应用的页码
        
        arr[i] = rand()%10;
        //cout << arr[i] << " ";
    }
    cout << endl;
    queue<int> FIFO;
    stack<int> LRU;

    //FIFO alforithm :
    cout << "FIFO序列如下: " << endl;
    map.clear();
    for(int i=0;i<N;i++){
        if(in(map,arr[i])){          //如果页码在内存中已经存在,输出true
            cout << "true" << endl;
            continue;
        }
            
        else{
            if(map.size()>=M){       //如果页码在内存中不存在,并且不是刚开始帧什么都没有的情况
                //int index = return_index(map,arr[i]);
                //cout << "index : " << index << endl;
                //FIFO.pop();
                //FIFO.push(arr[i]);
                map.erase(map.begin());   //头部出队列
                map.push_back(arr[i]);    //尾插
            }
            else{                    //初始状态,帧里面什么都没有,直接入队即可
                //FIFO.push(arr[i]);
                map.push_back(arr[i]);
            }
            num++;
            vector<int>::iterator v = map.begin();
            while( v != map.end()) {
                cout << *v << " ";
                v++;
            }
            cout << endl;
        }
    }
    num1 = num;
    cout << "总页数为: " << N << endl << "FIFO算法缺页数: " << num << endl;


    //LRU alaorithm :
    cout << endl << "LRU序列如下: " << endl;
    map.clear();
    num = 0;
    for(int i=0;i<N;i++){
        if(in(map,arr[i])){
            int index = return_index(map,arr[i]);   //与FIFO不同的地方,需要更新不断出现的元素,将它重新插入一遍
            map.erase(map.begin()+index);
            map.push_back(arr[i]);
            cout << "true" << endl;
            continue;
        }
        else{
            if(map.size()>=M){
                map.erase(map.begin());
                map.push_back(arr[i]);
            }
            else{
                map.push_back(arr[i]);
            }
            num++;
            vector<int>::iterator v = map.begin();
            while( v != map.end()) {
                cout << *v << " ";
                v++;
            }
            cout << endl;
        }
    }
    num2 = num;
    cout << "总页数为: " << N << endl << "LRU算法缺页数: "  << num << endl;



    //OPT alaorithm :
    cout << endl << "OPT序列如下: " << endl;
    map.clear();
    num = 0;
    
    for(int i=0;i<N;i++){
        if(in(map,arr[i])){
            // int index = return_index(map,arr[i]);
            // map.erase(map.begin()+index);
            // map.push_back(arr[i]);
            cout << "true" << endl;
            continue;
        }
        else{
            if(map.size()>=M){
                int pass = 0;
                int vis[M];
                for(int x=0;x<M;x++){
                    vis[x] = 0;
                }
                for(int j=i+1;j<N;j++){
                    for(int k=0;k<M;k++){
                        if(arr[j] == map[k]){
                            //cout << "i am " << arr[j] << endl;
                            int ind = return_index(map,arr[j]);
                            //cout << "index : " << ind << endl;
                            //cout << "arr : " << arr[j]  << endl;
                            if(vis[ind] == 1){
                                break;
                            }
                            else{
                                vis[ind] = 1;
                            }
                            pass++;
                            if(pass==M-1){
                                //cout << "pass = " << pass << "  goto !" << endl; 
                                goto This;
                            }
                            continue;
                        }
                    }
                }
This:           for(int j=0;j<M;j++){
                    if(vis[j] == 0){
                        //cout << "j == : " << j << endl;
                        map.erase(map.begin()+j);
                        map.push_back(arr[i]);
                        break;
                    }
                }
                
            }
            else{
                map.push_back(arr[i]);
            }
            num++;
            vector<int>::iterator v = map.begin();
            while( v != map.end()) {
                cout << *v << " ";
                v++;
            }
            cout << endl;
        }
    }
    num3 = num;
    cout << "总页数为: " << N << endl << "OPT算法缺页数: "  << num << endl;



    

    //Clock alaorithm 2.0 版本(循环队列) :
    cout << endl << "Clock序列如下: " << endl;
    map.clear();
    num = 0;
    vector<int> visit;
    
    int index = 0;
    for(int i=0;i<N;i++){
        if(in(map,arr[i])){
            int ind = return_index(map,arr[i]);
            //map.erase(map.begin()+index);
            visit[ind] = 1;
            //map.push_back(arr[i]);
            cout << "true" << endl;
            continue;
        }
        else{
            if(map.size()>=M){
                //int x = 0;
                while(1){
                    if(visit[index] == 0){
                        map[index] = arr[i];
                        visit[index] = 1;
                        index = (index+1) % M;
                        // map.erase(map.begin()+x);
                        // map.push_back(arr[i]);
                        // visit.erase(visit.begin()+x);
                        // visit.push_back(1);
                        break;
                    }
                    else{
                        visit[index] = 0;
                        index = (index+1) % M;
                    }
                }
            }
            else{
                map.push_back(arr[i]);
                visit.push_back(1);
            }
            num++;
            //cout << "元素 : ";
            vector<int>::iterator v = map.begin();
            while( v != map.end()) {
                cout << *v << " ";
                v++;
            }
            //cout << endl;
            //cout << "visit : "; 
            // vector<int>::iterator y = visit.begin();
            // while( y != visit.end()) {
            //     cout << *y << " ";
            //     y++;
            // }
            
            cout << endl;
        }
    }
    num4 = num;
    cout << "总页数为: " << N << endl << "Clock算法缺页数: "  << num << endl << endl;



    //Clock alaorithm 2.0 (FIFO为基础):
    cout << endl << "自创Clock序列如下: " << endl;
    map.clear();
    num = 0;
    visit.clear();
    for(int i=0;i<N;i++){
        if(in(map,arr[i])){
            int index = return_index(map,arr[i]);
            //map.erase(map.begin()+index);
            visit[index] = 1;
            //map.push_back(arr[i]);
            cout << "true" << endl;
            continue;
        }
        else{
            if(map.size()>=M){
                int x = 0;
                while(1){
                    if(visit[x] == 0){
                        map.erase(map.begin()+x);
                        map.push_back(arr[i]);
                        visit.erase(visit.begin()+x);
                        visit.push_back(1);
                        break;
                    }
                    else{
                        visit[x] = 0;
                        x = (x+1) % M;
                    }
                }
            }
            else{
                map.push_back(arr[i]);
                visit.push_back(1);
            }
            num++;
            //cout << "元素 : ";
            vector<int>::iterator v = map.begin();
            while( v != map.end()) {
                cout << *v << " ";
                v++;
            }
            //cout << endl;
            //cout << "visit : "; 
            // vector<int>::iterator y = visit.begin();
            // while( y != visit.end()) {
            //     cout << *y << " ";
            //     y++;
            // }
            
            cout << endl;
        }
    }
    num5 = num;
    cout << "总页数为: " << N << endl << "自创Clock算法缺页数: "  << num << endl << endl;



    cout << "综上所述 :" << endl;
    cout << "页码进入顺序为:" <<endl;
    for(int i=0;i<N;i++){ 
        cout << arr[i] << " ";
    }
    cout << endl;
    cout << "总页数为:" << N << endl;
    cout << "FIFO算法缺页数: "  << num1 << endl;
    cout << "LRU算法缺页数: "  << num2 << endl;
    cout << "OPT算法缺页数: "  << num3 << endl;
    cout << "Clock算法缺页数: "  << num4 << endl;
    cout << "自创Clock算法缺页数: "  << num5 << endl;

    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值