OS5 页面置换算法

来源:互联网 发布:python 生成高斯分布 编辑:程序博客网 时间:2024/05/21 09:32

页面置换算法

  • 实验
    编写程序实现虚拟存储管理中OPT,FIFO,LRU页面置换算法。
    1、任意给出一组页面访问顺序(如页面走向是1、2、5、7、5、7、1、4、3、5、6、4、3、2、1、5、2)。
    2、分配给该作业一定的物理块(如3块、4块等)。
    3、利用OPT,FIFO,LRU页面置换算法模拟页面置换过程并计算其缺页率。
    4、每访问一个页面均需给出内存中的内容(内存中的页面号),若有淘汰还需给出淘汰的页面号。
    5、通过给出特殊的页面访问顺序,分配不同的物理块,利用FIFO算法计算其缺页率,进一步理解Belady现象。
    6、(附加)实现CLOCK置换算法,修改位可在确定页面号时直接任意给出。
  • 分析
    • OPT
      对于给定的页面走向,从后续的页面看谁最晚用,那就选它置换就好了。实际中无法预测后续页面,所以OPT仅是对其他置换算法好坏的一个参考。
    • FIFO(belady现象)
      这就是按队列的方式来,谁先来的替换谁,注意如果下一个是0,队列中也有0并不对队列操作,也就是说仍按照队列的循序弹出,比如0在队首,如果要替换时,便直接将0弹出,而不考虑它是前一个刚替换的。
      关于belady现象,它是这几个算法中唯一个会随着物理块的增多,而有可能发生缺页增多的情况,原因是,它并没有考虑到页面的使用频率等等。例如:4 3 2 1 4 3 5 4 3 2 1 5 //会发生belady的一组页面走向
    • LRU
       最近最少使用,即要将最近最少使用的页面替换出去。教材上有两种实现方式:1、寄存器计数实现 2、利用堆栈来记录最近的使用情况,每个最新访问的都要放到栈顶。由于置顶的过程,有大量的出栈入栈,为了方便操作,利用一个数组模拟的堆栈操作。
    • CLOCK
       增加了访问位A,修改位M。将置换页面分为了四类(从最优置换到最差):(0,0)(0,1)(1,0)(1,1)。
      算法:
      1.查找一类(0,0),找到一个即替换,没有找到则2
      2.查找二类(0,1)页面,并在查找的过程中将A=0,找到则替换,没有进入3(这时所有的A均已为0)
      3.继续查找一类(0,0),如果找到,则替换,没有进入4(这时的页面只可能是(0,1),必能替换出去)
      4.最后一定能找到(0,1)的页面替换出去
       
  • code
#include<iostream>#include<list>using namespace std;void opt(int *d,int size,int psize){    int incount=0;    int *stk=new int[psize];    int *flag=new int[psize];    //stack满了,对页面走向向后遍历,找到最后访问的    int stk_size=0;    int isIn=0;    for(int i=0;i<size;i++)    {        cout<<"---------------------seq:"<<i<<"-"<<d[i]<<endl;        isIn=0;        //检查是否就在stack中        for(int j=0;j<psize;j++)        {            if(stk[j]==d[i])            {                incount++;                cout<<d[i]<<" in stack 命中"<<endl;                isIn=1;                break;            }        }        if(isIn==1)          continue;        if(stk_size<psize)        {            cout<<"push"<<d[i]<<endl;            //push            stk[stk_size]=d[i];            stk_size++;        }else        {            for(int j=0;j<psize;j++)              flag[j]=-1;            int last=i;            for(int j=i;j<size;j++)            {                for(int k=0;k<psize;k++)                {                    if(stk[k]==d[j]&&flag[k]==-1)                    {                        flag[k]=j;                        last=j;                    }                }            }            //get last            for(int j=0;j<psize;j++)              cout<<stk[j]<<"-"<<flag[j]<<" ";            cout<<endl;            int pos=0;            for(int j=0;j<psize;j++)            {              if(flag[j]==-1)              {                  pos=j;                  break;              }else if(flag[j]==last)              {                  pos=j;              }            }            cout<<"pop "<<stk[pos]<<" push "<<d[i]<<endl;                  //pop--并没有用到stack的性质,直接替换            stk[pos]=d[i];        }    }    cout<<"opt缺页率:"<<double(size-incount)/size<<endl;    delete[]flag;    delete[]stk;}void fifo(int *d,int size,int psize){    int incount=0;    int *que=new int[psize];    int que_size=0;    int pos=0;    int isIn=0;    for(int i=0;i<size;i++)    {        cout<<"-------------------------seq:"<<i<<"-"<<d[i]<<endl;        isIn=0;        //search in que        for(int j=0;j<que_size;j++)        {            if(que[j]==d[i])            {                cout<<d[i]<<" in que 命中"<<endl;                incount++;                isIn=1;                break;            }        }        if(isIn==1)          continue;        if(que_size<psize)        {            que[que_size]=d[i];            cout<<d[i]<<" 入队"<<endl;            que_size++;        }else        {            pos%=psize;            cout<<que[pos]<<" 出队 "<<d[i]<<" 入队"<<endl;            que[pos++]=d[i];        }    }    cout<<"共命中:"<<incount<<endl;    cout<<"缺页率"<<double(size-incount)/size<<endl;    delete []que;}//将指定元素移动到栈顶void move(int *stk,int begin,int size){    int tmp=0;    for(int i=begin+1;i<size;i++)    {        tmp=stk[i];        stk[i]=stk[i-1];        stk[i-1]=tmp;    }}void lru(int *d,int size,int psize){    int incount=0;    int *stk=new int[psize];    int stk_size=0;    int isIn=0;    for(int i=0;i<size;i++)    {        cout<<"------------------------seq:"<<i<<"-"<<d[i]<<endl;        for(int j=0;j<stk_size;j++)          cout<<stk[j]<<" ";        isIn=0;        //最新访问的放栈顶        for(int j=0;j<stk_size;j++)        {            if(stk[j]==d[i])            {                incount++;                cout<<d[i]<<" 命中"<<endl;                cout<<"栈顶变化:"<<stk[stk_size-1]<<" -> ";                isIn=1;                move(stk,j,stk_size);                cout<<stk[stk_size-1]<<endl;                break;            }        }        if(isIn==1)          continue;        if(stk_size<psize)        {            cout<<d[i]<<" 入栈"<<endl;            stk[stk_size++]=d[i];        }else//替换        {            move(stk,0,stk_size);            cout<<stk[stk_size-1]<<" 出栈"<<endl;            cout<<d[i]<<" 入栈"<<endl;            stk[stk_size-1]=d[i];        }    }    cout<<"共命中:"<<incount<<endl;    cout<<"缺页率"<<double(size-incount)/size<<endl;    delete []stk;}void belady(int *d,int size){    int psize=0;    while(true)    {        cout<<"input psize(<=0 exit)"<<endl;        cin>>psize;        cout<<psize<<endl;        if(psize<=0)          break;        else          fifo(d,size,psize);    }}struct M{    int D;     int A;    int M;    int flag;};//第一轮选择M mclock1(list<M>&mlist){    cout<<"search A=0 M=0"<<endl;    M tmp;    list<M>::iterator it=mlist.begin();    for( ;it!=mlist.end();it++)    {        if(it->A==0&&it->M==0)        {            tmp=*it;            tmp.flag=0;            //淘汰            mlist.erase(it);            return tmp;        }    }    tmp.flag=-1;    return tmp;}//第二轮修改AM mclock2(list<M>&mlist){    cout<<"search A=0 M=1"<<endl;    M tmp;    list<M>::iterator it=mlist.begin();    for( ;it!=mlist.end();it++)    {        if(it->A==0&&it->M==1)        {            tmp=*it;            tmp.flag=0;            //淘汰            mlist.erase(it);            return tmp;        }        it->A=0;    }    tmp.flag=-1;    return tmp;}void mclock(int *d,int size,int psize){    cout<<"赋予"<<size<<"个修改位(1修改,0未修改)"<<endl;    M tmp;    list<M> mlist;    list<M> mdata;    for(int i=0;i<size;i++)    {        tmp.D=d[i];        cin>>tmp.A>>tmp.M;        mdata.push_back(tmp);    }    int seq=0;    while(mdata.size()>0)    {        cout<<"----------------------seq:"<<seq++<<"-"<<mdata.front().D<<endl;        if(mlist.size()>=psize)        {            tmp=mclock1(mlist);//loop 1            if(tmp.flag!=0)            {                tmp=mclock2(mlist);//loop 2                if(tmp.flag!=0)                {                    tmp=mclock1(mlist);//loop 3                    if(tmp.flag==-1)                    {                        tmp=mclock2(mlist);//loop4                        if(tmp.flag==-1)                        {                            cout<<"error:clock alg exit"<<endl;                            return;                        }                    }                }            }            cout<<"淘汰:"<<tmp.D<<"-"<<tmp.A<<"-"<<tmp.M<<endl;        }        cout<<"insert:"<<mdata.front().D<<"-"<<mdata.front().A<<"-"<<                mdata.front().M<<endl;        mlist.push_back(mdata.front());        mdata.pop_front();    }}int main(){    int tmp=0;    int size=0;    int psize=0;    cout<<"输入分配的物理块数 页面访问顺序(size,seq[size])"<<endl;    cin>>psize>>size;    int *data=new int[size];    for(int i=0;i<size;i++)      cin>>data[i];    cout<<"mode opt:0 fifo:1 lru:2 belady:3 clock:4 exit:-1"<<endl;    while(tmp>=0)    {        cin>>tmp;        switch(tmp)        {            case 0:                opt(data,size,psize);                break;            case 1:                fifo(data,size,psize);                break;            case 2:                lru(data,size,psize);                break;            case 3:                belady(data,size);                break;            case 4:                mclock(data,size,psize);                break;            default:                cout<<"exit"<<endl;        }    }    delete[] data;    return 0;}
  • belady测试用例
3 12 4 3 2 1 4 3 5 4 3 2 1 5  //会发生belady的一组页面走向3 //belady3  //不同的物理块数456-1 //exit
原创粉丝点击