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)的页面替换出去
- OPT
- 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
阅读全文
0 0
- OS5 页面置换算法
- 页面置换算法
- 页面置换算法
- 页面置换算法
- 页面置换算法
- 页面置换算法
- 操作系统页面置换算法
- 页面置换算法解析
- 操作系统页面置换算法
- 页面置换算法初步
- 页面置换算法
- 页面置换算法
- 页面置换算法
- 页面置换算法
- 页面置换算法
- 页面置换算法LRU
- 【操作系统】页面置换算法
- 页面置换算法
- 图片隐藏数据的技术
- 在 Ios下编译cocos
- Thinking in java -6 隐藏的实现 Hidden implementation
- 51 Nod 机器人走方格
- 标注与注记的区别和联系
- OS5 页面置换算法
- 如何修改论文,能够避开查重?
- python zip()并行遍历
- JAVA 4.1 方法
- 编程之美3.11
- 不同类型数据间的转换
- Sublime Text3使用教程-安装与插件以及快捷键使用
- 表单
- 用struts2搭建一个登录的例子