操作系统——请求调页存储管理方式的各种模拟
来源:互联网 发布:汉语言文学就业知乎 编辑:程序博客网 时间:2024/05/18 00:57
1.设计目的
通过对页面、页表、地址转换和页面置换过程的模拟,加深对请求调页系统的原理和实现过程的理解。
2.设计内容
1)假设每个页面中可存放10条指令,分配给作业的内存块数为4。
2)用c语言模拟一个作业的执行过程,该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。在模拟过程中,如果所访问的指令已在内存,则显示其物理地址,并转下一条指令。如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。如果4个内存块均已装入该作业,则需进行页面置换,最后显示其物理地址,并转下一条指令。
在所有320指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
3)置换算法:
1、采用先进先出(FIFO)置换算法。
2、最近最久未使用(LRU)算法。
3、最佳置换(OPT)算法。
4、最少访问(LFU)算法。
提示:
(1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成:
① 50%的指令是顺序执行的;
② 25%的指令是均匀分布在前地址部分;
③ 25%的指令是均匀分布在后地址部分;
具体的实施方法是:
① 在[0,319]的指令地址之间随机选取一起点m;
② 顺序执行一条指令,即执行地址为m+1的指令;
③ 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m′;
④ 顺序执行一条指令,其地址为m′+1的指令;
⑤ 在后地址[m′+2,319]中随机选取一条指令并执行;
⑥ 重复上述步骤①~⑤,直到执行320次指令。
(2)将指令序列变换为页地址流
① 设页面大小为1K;
② 用户内存容量为4页到32页;
③ 用户虚存容里为32K。
在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第0条~第9条指令为第0页(对应虚存地址为[0,9]);
第10条~第19条指令为第1页(对应虚存地址为[10,19]);
……
……
第310条~第319条指令为第31页(对应虚存地址为[310,319])。
按以上方式,用户指令可组成32页。
(3)计算先进先出(FIFO)算法在不同内存容量下的命中率。
其中,命中率=1-页面失效次数/页地址流长度
1、采用先进先出(FIFO)置换算法
#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cmath>#include<ctime>#include<cstring>#include<cstdlib>using namespace std;struct node{ int i,j;//进入内存的页面数和页内地址 int p;//页面值 int k;//记录页面在内存中中的位置1~4};struct NN{ int flag;//表示是否存在在内存中 int id;//在内存中的位置1~4};int page[33][11];//保存页面和指令int qk=0,sss=0;//用于记录缺页的次数queue<node> q;int hashmap[330];//一共用320条指令double random();//生成[0,1]之间的均匀数字int random(int m);//生成[0,m-1]之间的均匀随机数void Init(int r);//定义初始化函数,初始值为rvoid Init_Page();//初始化页面void Show();//显示页面信息int Address(int i,int j);//计算每个页面对应的地址void Oper_FIFO(int n);//FIFO操作算法void Print();int main(){ freopen("input.txt","r",stdin); freopen("output13.txt","w",stdout); Init(6); printf("生成的随机数\n"); Show(); Init_Page(); printf("对应的调入页面\n"); Show(); Oper_FIFO(4); Print();return 0;}double random(){//生成[0,1]之间的均匀数字 return (double) rand() / RAND_MAX;}int random(int m){//生成[0,m-1]之间的均匀随机数 return (int) (random()*(m-1)+0.5);}int Address(int i,int j){//计算每个页面对应的地址 return i*10+j;}void Init(int r){//初始化函数,初始化指令 srand(time(NULL)); int ok=1,j=0; for(int i=0;i<32;){ if(j==10){ i++; j=0; if(i>=32) break; } if(ok==1){ r=random(320); page[i][j++]=r; page[i][j++]=r+1; ok=2;//标记进入第二个随机数 continue; } if(ok==2){ int k=(random(r+1));//1-m+1随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=3;//标记下次进入第二个随机数 continue; } if(ok==3){ int k=(r+2)+(random(320-r-2));//在m+2和320之间随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=1;//下次进入标记进入第一个随机数 continue; } }}void Init_Page(){//初始化页面 for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ page[i][j]=page[i][j]/10; } }}void Oper_FIFO(int n){//操作函数,先进先出 int s=0;//内存的首指 memset(hashmap,0,sizeof(hashmap));//用于记录当前页面是否在内存中,0:不在,1:在 for(int i=0;i<32;i++){//下面是有320条指令的作业的运行情况 for(int j=0;j<10;j++){ if(hashmap[page[i][j]]==1){//页面在内存中 printf("当前访问页面在内存中,当前页面的地址为%d\n",Address(i,j)); sss++; } else{//当前页面不在内存中,增加缺页次数,并调入内存 qk++;//增加缺页次数 node temp,temp1; temp.i=i; temp.j=j; temp.p=page[i][j]; if(q.size()<n){//内存使用小于4,直接调入 printf("页面不存在,有空的内存空间,直接调入。\n"); temp.k=s%4+1; hashmap[page[i][j]]=1; q.push(temp); //记录此页已在内存中 ++s; } if(q.size()==n){//内存已占用4,按先进先出移除一个页面 temp1=q.front();//取出队首元素 q.pop(); printf("页面不存在,内存空间已满,按算法移除页面为:%d,其地址为:%d,它占用的内存块为:%d\n",temp1.p,Address(temp1.i,temp1.j),temp1.k); temp.k=temp1.k; hashmap[temp1.p]=0;//移除的页面变为未存在 q.push(temp); hashmap[page[i][j]]=1;//进入的页面表示为存在 } } } }}void Show(){ for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ printf("%d ",page[i][j]); } printf("\n"); }}void Print(){ printf("缺页次数为:%d 匹配成功次数:%d\n",qk,sss); printf("缺页率为:%.3lf%%\n",1.0*qk/320*100);}
2、最近最久未使用(LRU)算法
/** *操作系统作业 *题目14:LRU */#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cmath>#include<ctime>#include<cstring>#include<cstdlib>using namespace std;struct node{ int i,j;//进入内存的页面数和页内地址 int p;//页面值 int k;//记录页面在内存中中的位置1~4};struct NN{ int flag;//表示是否存在在内存中 int id;//在内存中的位置1~4};int page[33][11];//保存页面和指令int qk=0;//用于记录缺页的次数node q[136];//定义内存块的个数clock_t hashmap[330];//一共用320条指令double random();//生成[0,1]之间的均匀数字int random(int m);//生成[0,m-1]之间的均匀随机数void Init(int r);//定义初始化函数,初始值为rvoid Init_Page();//定义page初始化函数void Show();//显示页面信息int Address(int i,int j);//计算每个页面对应的地址void Oper_LRU(int n);//LRU操作算法void Print();int cmp(node a,node b);//定义比较函数int main(){ freopen("input14.txt","r",stdin); freopen("output14.txt","w",stdout); int n; Init(56); Init_Page(); printf("调入页面:\n"); Show();s scanf("%d",&n); Oper_LRU(n); Print();return 0;}double random(){//生成[0,1]之间的均匀数字 return (double) rand() / RAND_MAX;}int random(int m){//生成[0,m-1]之间的均匀随机数 return (int) (random()*(m-1)+0.5);}int Address(int i,int j){//计算每个页面对应的地址 return i*10+j;}void Init(int r){//初始化函数,初始化指令 srand(time(NULL)); int ok=1,j=0; for(int i=0;i<32;){ if(j==10){ i++; j=0; if(i>=32) break; } if(ok==1){ r=random(320); page[i][j++]=r; page[i][j++]=r+1; ok=2;//标记进入第二个随机数 continue; } if(ok==2){ int k=(random(r+1));//1-m+1随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=3;//标记下次进入第二个随机数 continue; } if(ok==3){ int k=(r+2)+(random(320-r-2));//在m+2和320之间随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=1;//下次进入标记进入第一个随机数 continue; } }}void Init_Page(){//初始化页面 for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ page[i][j]=page[i][j]/10; } }}void Oper_LRU(int n){//操作函数,先进先出 int s=0;//内存的首指 memset(hashmap,0,sizeof(hashmap));//用于记录当前页面是否在内存中,0:不在,1-4:在某个内存 memset(q,0,sizeof(q)); for(int i=0;i<32;i++){//下面是有320条指令的作业的运行情况 for(int j=0;j<10;j++){ if(hashmap[page[i][j]]>=1){//页面在内存中 //printf("当前访问页面在内存中,占用内存的地址为:%d,当前页面的地址为%d\n",hashmap[page[i][j]].id+1,Address(i,j)); hashmap[page[i][j]]=clock();//记录最近一次访问时间 sort(q,q+s,cmp);//每次更改重新排序1~4 } else{//当前页面不在内存中,增加缺页次数,并调入内存 qk++;//增加缺页次数 node temp,temp1; temp.i=i; temp.j=j; temp.p=page[i][j]; if(s<n){//内存使用小于4,直接调入 //printf("页面不存在,有空的内存空间,直接调入。\n"); temp.k=s+1; hashmap[page[i][j]]=clock();//记录进入时间 q[s++]=temp; //记录此页已在内存中 } else if(s>=n){//内存已占用4,按先进先出移除一个页面 temp1=q[0];//取出队首元素 //printf("页面不存在,内存空间已满,按算法移除页面为:%d,其地址为:%d,它占用的内存块为:%d\n",temp1.p,Address(temp1.i,temp1.j),temp1.k); temp.k=temp1.k; hashmap[page[temp1.i][temp1.j]]=0;//变为未访问 q[0]=temp; hashmap[page[i][j]]=clock();//记录进入时间 } sort(q,q+s,cmp);//每次更改重新排序1~4 } for(int k=0;k<n;k++){ printf("%02d ",q[k].p); } printf("\n"); } }}void Show(){ for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ printf("%d ",page[i][j]); } printf("\n"); }}void Print(){ printf("缺页次数为:%d\n",qk); printf("命中率为:%.3lf%%\n",1.0*(320-qk)/320*100);}int cmp(node a,node b){//实现比较函数 return hashmap[a.p]<hashmap[b.p];//最近最少使用的页面小的排在最前面}
3、最佳置换(OPT)算法
/** *操作系统作业 *题目15:OPT */#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cmath>#include<ctime>#include<cstring>#include<cstdlib>using namespace std;struct node{ int i,j;//进入内存的页面数和页内地址 int p;//页面值 int k;//记录页面在内存中中的位置1~4};struct NN{ int flag;//表示是否存在在内存中 int id;//在内存中的位置1~4};int page[33][11];//保存页面和指令int qk=0;//用于记录缺页的次数node q[136];//定义内存块的个数int hashmap[330];//一共用320条指令queue<int> qp[325];//保存每一个页面在未来的位置到队列中double random();//生成[0,1]之间的均匀数字int random(int m);//生成[0,m-1]之间的均匀随机数void Init(int r);//定义初始化函数,初始值为rvoid Init_Page();//定义page初始化函数void Show();//显示页面信息int Address(int i,int j);//计算每个页面对应的地址void Oper_OPT(int n);//LRU操作算法void Print();int cmp(node a,node b);//定义比较函数int main(){ /** freopen("input.txt","r",stdin); freopen("output15.txt","w",stdout); **/ Init(56); Init_Page(); printf("调入页面:\n"); Show(); Oper_OPT(4);//此处传入的参数不同,可用内存不同 Print();return 0;}double random(){//生成[0,1]之间的均匀数字 return (double) rand() / RAND_MAX;}int random(int m){//生成[0,m-1]之间的均匀随机数 return (int) (random()*(m-1)+0.5);}int Address(int i,int j){//计算每个页面对应的地址 return i*10+j;}void Init(int r){//初始化函数,初始化指令 srand(time(NULL)); int ok=1,j=0; for(int i=0;i<32;){ if(j==10){ i++; j=0; if(i>=32) break; } if(ok==1){ r=random(320); page[i][j++]=r; page[i][j++]=r+1; ok=2;//标记进入第二个随机数 continue; } if(ok==2){ int k=(random(r+1));//1-m+1随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=3;//标记下次进入第二个随机数 continue; } if(ok==3){ int k=(r+2)+(random(320-r-2));//在m+2和320之间随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=1;//下次进入标记进入第一个随机数 continue; } }}void Init_Page(){//初始化页面 for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ page[i][j]=page[i][j]/10; qp[page[i][j]].push(i*10+j);//保存每个页面出现的位置在队列中 } } for(int i=0;i<=320;i++){//将不足的页面赋值为321;标记此页面在以后不会出现,一定会在最前面被替换 while(qp[i].size()<=320){ qp[i].push(322); } }}void Oper_OPT(int n){//操作函数,先进先出 int s=0;//内存的首指 memset(hashmap,0,sizeof(hashmap));//用于记录当前页面是否在内存中,0:不在,1-4:在某个内存 memset(q,0,sizeof(q)); for(int i=0;i<32;i++){//下面是有320条指令的作业的运行情况 for(int j=0;j<10;j++){ if(hashmap[page[i][j]]==1){//页面在内存中 //printf("当前访问页面在内存中,占用内存的地址为:%d,当前页面的地址为%d\n",hashmap[page[i][j]].id+1,Address(i,j)); qp[page[i][j]].pop();//从队列中移除当前页面的当前位置 sort(q,q+s,cmp);//每次更改重新排序1~4 } else{//当前页面不在内存中,增加缺页次数,并调入内存 qk++;//增加缺页次数 node temp,temp1; temp.i=i; temp.j=j; temp.p=page[i][j]; qp[page[i][j]].pop();//从队列中移除当前页面的当前位置 if(s<n){//内存使用小于4,直接调入 //printf("页面不存在,有空的内存空间,直接调入。\n"); temp.k=s+1; hashmap[page[i][j]]=1;//记录已在内存 q[s++]=temp; //记录此页已在内存中 } else if(s>=n){//内存已占用4,按先进先出移除一个页面 temp1=q[0];//取出队首元素 //printf("页面不存在,内存空间已满,按算法移除页面为:%d,其地址为:%d,它占用的内存块为:%d\n",temp1.p,Address(temp1.i,temp1.j),temp1.k); temp.k=temp1.k; hashmap[page[temp1.i][temp1.j]]=0;//变为未访问 q[0]=temp; hashmap[page[i][j]]=1;//记录进入内存 } sort(q,q+s,cmp);//每次更改重新排序1~4 } for(int k=0;k<n;k++){ printf("%02d ",q[k].p); } printf("\n"); } }}void Show(){ for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ printf("%d ",page[i][j]); } printf("\n"); }}void Print(){ printf("缺页次数为:%d\n",qk); printf("命中率为:%.3lf%%\n",1.0*(320-qk)/320*100);}int cmp(node a,node b){//实现比较函数 return qp[a.p].front()>qp[b.p].front();//未来一段时间出现的晚的在前面}
4、最少访问(LFU)算法
/** *操作刺痛作业 *题目16:LFU */#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cmath>#include<ctime>#include<cstring>#include<cstdlib>using namespace std;struct node{ int i,j;//进入内存的页面数和页内地址 int p;//页面值 int k;//记录页面在内存中中的位置1~4};struct NN{ int flag;//表示是否存在在内存中 int id;//在内存中的位置1~4};int page[33][11];//保存页面和指令int qk=0;//用于记录缺页的次数node q[136];//定义内存块的个数int hashmap[330];//一共用320条指令double random();//生成[0,1]之间的均匀数字int random(int m);//生成[0,m-1]之间的均匀随机数void Init(int r);//定义初始化函数,初始值为rvoid Init_Page();//定义page初始化函数void Show();//显示页面信息int Address(int i,int j);//计算每个页面对应的地址void Oper_LFU(int n);//FIFO操作算法void Print();int cmp(node a,node b);//定义比较函数int main(){ freopen("input.txt","r",stdin); freopen("output16.txt","w",stdout); Init(56); Init_Page(); printf("调入页面:\n"); Show(); Oper_LFU(4); Print();return 0;}double random(){//生成[0,1]之间的均匀数字 return (double) rand() / RAND_MAX;}int random(int m){//生成[0,m-1]之间的均匀随机数 return (int) (random()*(m-1)+0.5);}int Address(int i,int j){//计算每个页面对应的地址 return i*10+j;}void Init(int r){//初始化函数,初始化指令 srand(time(NULL)); int ok=1,j=0; for(int i=0;i<32;){ if(j==10){ i++; j=0; if(i>=32) break; } if(ok==1){ r=random(320); page[i][j++]=r; page[i][j++]=r+1; ok=2;//标记进入第二个随机数 continue; } if(ok==2){ int k=(random(r+1));//1-m+1随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=3;//标记下次进入第二个随机数 continue; } if(ok==3){ int k=(r+2)+(random(320-r-2));//在m+2和320之间随机取一个数 page[i][j++]=k; page[i][j++]=k+1; ok=1;//下次进入标记进入第一个随机数 continue; } }}void Init_Page(){//初始化页面 for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ page[i][j]=page[i][j]/10; } }}void Oper_LFU(int n){//操作函数,先进先出 int s=0;//内存的首指 memset(hashmap,0,sizeof(hashmap));//用于记录当前页面是否在内存中,0:不在,1-4:在某个内存 memset(q,0,sizeof(q)); for(int i=0;i<32;i++){//下面是有320条指令的作业的运行情况 for(int j=0;j<10;j++){ if(hashmap[page[i][j]]>=1){//页面在内存中 //printf("当前访问页面在内存中,占用内存的地址为:%d,当前页面的地址为%d\n",hashmap[page[i][j]].id+1,Address(i,j)); hashmap[page[i][j]]++;//增加访问次数 sort(q,q+s,cmp);//每次更改重新排序1~4 } else{//当前页面不在内存中,增加缺页次数,并调入内存 qk++;//增加缺页次数 node temp,temp1; temp.i=i; temp.j=j; temp.p=page[i][j]; if(s<n){//内存使用小于4,直接调入 //printf("页面不存在,有空的内存空间,直接调入。\n"); temp.k=s+1; hashmap[page[i][j]]=1; q[s++]=temp; //记录此页已在内存中 } else if(s>=n){//内存已占用4,按先进先出移除一个页面 temp1=q[0];//取出队首元素 //printf("页面不存在,内存空间已满,按算法移除页面为:%d,其地址为:%d,它占用的内存块为:%d\n",temp1.p,Address(temp1.i,temp1.j),temp1.k); temp.k=temp1.k; hashmap[page[temp1.i][temp1.j]]=0;//变为未访问 q[0]=temp; hashmap[page[i][j]]=1; } sort(q,q+s,cmp);//每次更改重新排序1~4 } for(int k=0;k<n;k++){ printf("%02d ",q[k].p); } printf("\n"); } }}void Show(){ for(int i=0;i<32;i++){ for(int j=0;j<10;j++){ printf("%d ",page[i][j]); } printf("\n"); }}void Print(){ printf("缺页次数为:%d\n",qk); printf("命中率为:%.3lf%%\n",1.0*(320-qk)/320*100);}int cmp(node a,node b){//实现比较函数 return hashmap[a.p]<hashmap[b.p];//访问次数小的排在最前面}
- 操作系统——请求调页存储管理方式的各种模拟
- 【实验】请求调页存储管理方式的模拟
- 请求调页存储管理方式的模拟-python实现
- OS 请求调页存储管理方式的FIFO、LRU、OPT、LFU置换算法模拟
- 【操作系统】请求分页存储管理方式
- 页式存储管理(模拟操作系统)
- 操作系统试验七——模拟虚拟存储管理(上)
- 操作系统实验七——模拟虚拟存储管理(下)
- 操作系统概论(7)——请求分页存储管理
- 【操作系统】虚拟存储器--请求分段存储管理方式
- 操作系统—存储管理
- 模拟请求页式存储管理--LRU
- 校招季——操作系统的存储管理
- 《操作系统》—页式存储管理
- 【操作系统】分页存储管理方式
- 【操作系统】分段存储管理方式
- 操作系统——存储管理
- 操作系统——存储管理
- spring 注入java.util.Properties 属性两种xml中的配置练习
- 树链剖分(基于点权)bzoj1036
- 05-2. Saving James Bond - Easy Version
- [c++ STL]: std::find, std::find_if, std::distance
- rethat下yum出现no package
- 操作系统——请求调页存储管理方式的各种模拟
- 苹果公司的“拿来”之道:Swift借自其它编程语言的10大功能
- 树与二叉树——思维导图
- Bugzilla使用说明
- Genymotion 性能完爆安卓模拟器,可取而代之.
- 配置Apache的虚拟主机
- 开通博客
- Java编程专题思维导图
- ionic初探