请求页式存储管理中常用页面置换算法模拟

合集下载

《操作系统》实验五:页面置换算法模拟

《操作系统》实验五:页面置换算法模拟

实验五. 请求页式存储管理的模拟[实验内容]:熟悉虚拟存储管理的各种页面置换算法,并编写模拟程序实现请求页式存储管理的页面置换算法----最近最久未使用算法(LRU),要求在每次产生置换时显示页面分配状态和缺页率。

[实验要求]:1、运行给出的实验程序,查看执行情况,进而分析算法的执行过程,在理解FIFO页面置换算法和最近最久未使用算法(LRU)置换算法后,给出最佳置换算法的模拟程序实现,并集成到参考程序中。

2、执行2个页面置换模拟程序,分析缺页率的情况。

最好页框数和访问序列长度可调节,在使用同一组访问序列数据的情况下,改变页框数并执行2个页面置换模拟程序,查看缺页率的变化。

3、在每次产生置换时要求显示分配状态和缺页率。

程序的地址访问序列通过随机数产生,要求具有足够的长度。

最好页框数和访问序列长度可调节。

实验的执行结果如下图所示(左下图为FIFO执行结果,右下图为LRU执行结果):程序源代码: #include <libio.h> #include "windows.h" #include <conio.h>#include <stdlib.h>#include <fstream.h>#include <io.h>#include <string.h>#include <stdio.h>void initialize(); //初始化相关数据结构void createps(); //随机生成访问序列void displayinfo(); //显示当前状态及缺页情况void fifo(); //先进先出算法int findpage(); //查找页面是否在内存void lru(); //最近最久未使用算法int invalidcount = 0; // 缺页次数int vpoint; //页面访问指针int pageframe[10]; // 分配的页框int pagehistory[10]; //记录页框中数据的访问历史int rpoint; //页面替换指针int inpflag; //缺页标志,0为不缺页,1为缺页struct PageInfo //页面信息结构{int serial[100]; // 模拟的最大访问页面数,实际控制在20以上int flag; // 标志位,0表示无页面访问数据int diseffect; // 缺页次数int total_pf; // 分配的页框数int total_pn; // 访问页面序列长度} pf_info;//////////////////////////////////////////////////////////////////////// //初始化相关数据结构void initialize(){int i,pf;inpflag=0; //缺页标志,0为不缺页,1为缺页pf_info.diseffect =0; // 缺页次数pf_info.flag =0; // 标志位,0表示无页面访问数据printf("\n请输入要分配的页框数:"); // 自定义分配的页框数scanf("%d",&pf);pf_info.total_pf =pf;for(i=0;i<100;i++) // 清空页面序列{pf_info.serial[i]=-1;}}///////////////////////////////////////////////////////////////////// 随机生成访问序列void createps(void ){int s,i,pn;initialize(); //初始化相关数据结构printf("\n请输入要随机生成访问序列的长度:"); //自定义随机生成访问序列的长度scanf("%d",&pn);srand(rand()); //初始化随机数队列的"种子"s=((float) rand() / 32767) * 50 + pn; // 随机产生页面序列长度pf_info.total_pn = s;for(i=0;i<s;i++) //产生随机访问序列{pf_info.serial[i]=((float) rand() / 32767) * 16 ; //随机数的大小在0-15之间}}////////////////////////////////////////////////////////////////////////// 显示当前状态及缺页情况void displayinfo(void){int i,n;if(vpoint==0){printf("\n=============页面访问序列=============\n");for(i=0; i<pf_info.total_pn; i++){printf("%4d",pf_info.serial[i]);if ((i+1) % 10 ==0) printf("\n"); //每行显示10个}printf("\n======================================\n"); }printf("访问%3d : 内存<",pf_info.serial[vpoint]);for(n=0;n<pf_info.total_pf;n++) // 页框信息{if (pageframe[n] >=0)printf("%3d",pageframe[n]);elseprintf(" ");}printf(" >");if(inpflag==1) //缺页标志,0为不缺页,1为缺页{printf(" ==>缺页");printf("缺页率%3.1f",(float)(pf_info.diseffect)*100.00/vpoint);}printf("\n");}//////////////////////////////////////////////////////////////////////// // 查找页面是否在内存,1为在内存,0为不在即缺页int findpage(int page){int n;for(n=0;n<pf_info.total_pf;n++){pagehistory[n] ++; // 访问历史加1}for(n=0;n<pf_info.total_pf;n++){if (pageframe[n]==page ){inpflag=0 ; //inpflag缺页标志,0为不缺页,1为缺页pagehistory[n]=0; //置访问历史为0return 1;}}inpflag=1; //页面不存在,缺页return 0;}//////////////////////////////////////////////////////////////////////// // FIFO页面置换算法void fifo(void){int n,count,pstate;rpoint=0; // 页面替换指针初始化为0invalidcount = 0; // 缺页数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满是所有的页框for(n=0;n<pf_info.total_pf;n++) // 清除页框信息{pageframe[n]=-1;}inpflag=0; //缺页标志,0为不缺页,1为缺页for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]); //查找页面是否在内存if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0) // 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0) // 页不存在则置换页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;pf_info.diseffect++; // 缺页次数加1 }}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束getch();return;}/////////////////////////////////////////////////////////////////// // LRU页面置换算法void lru(void){int n,count,pstate,max;rpoint=0; // 页面替换指针invalidcount = 0; // 缺页次数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满所有的页框for(n=0;n<pf_info.total_pf;n++){pageframe[n]=-1; // 清除页框信息pagehistory[n]=0; // 清除页框历史}inpflag=0; //缺页标志,0为不缺页,1为缺页for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]); //查找页面是否在内存if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0) // 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint]; //把要调入的页面放入一个空的页框里rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0)// 页不存在则置换页面{max=0;for(n=1;n<pf_info.total_pf;n++){if(pagehistory[n]>pagehistory[max]){max=n;}}rpoint=max;pageframe[rpoint]=pf_info.serial[vpoint];pagehistory[rpoint]=0;pf_info.diseffect++; // 缺页次数加1 }}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}/////////////////////最佳置换算法自己完成/////////////////////////////////////////////////////////////////// // 主函数int main(){char ch;system("cls") ;while ( true ){printf("*******************************************\n");printf(" 若要执行FIFO页面置算法请按1\n");printf(" 若要执行LRU 页面置算法请按2\n");printf(" 若要退出请按3\n") ;printf("*******************************************\n");printf( "Enter your choice (1 or 2 or 3): ");do{ //如果输入信息不正确,继续输入ch = (char)getch() ;}while(ch != '1' && ch != '2'&& ch != '3');printf("\n\n你按的是:%c ,现在为你执行对应操作。

常用页面置换算法模拟实验

常用页面置换算法模拟实验

存储管理常用页面置换算法模拟实验实验目的通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。

实验内容设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。

1、最佳淘汰算法(OPT)2、先进先出的算法(FIFO)3、最近最久未使用算法(LRU)4、最不经常使用算法(LFU)5、最近未使用算法(NUR)命中率=1-页面失效次数/页地址流长度实验准备本实验的程序设计基本上按照实验内容进行。

即首先用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。

(1)通过随机数产生一个指令序列,共320条指令。

指令的地址按下述原则生成:A:50%的指令是顺序执行的B:25%的指令是均匀分布在前地址部分C:25%的指令是均匀分布在后地址部分具体的实施方法是:A:在[0,319]的指令地址之间随机选取一起点mB:顺序执行一条指令,即执行地址为m+1的指令C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’D:顺序执行一条指令,其地址为m’+1E:在后地址[m’+2,319]中随机选取一条指令并执行F:重复步骤A-E,直到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页。

实验指导一、虚拟存储系统UNIX中,为了提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行;一个进程只需将其一部分(段或页)调入内存便可运行;还支持请求调页的存储管理方式。

页面置换-操作系统课程设计

页面置换-操作系统课程设计

页面置换算法模拟1、设计目的通过请求页式管理方式中页面置换算法的模拟设计,了解虚拟存储的特点,掌握请求页式存储管理中的页面置换算法。

2、任务及要求2.1 设计任务模拟实现先进先出算法(FIFO)、最近最少使用算法(LRU)、最优页置换算法(OPT),并计算命中率。

2.2 设计要求2.2.1 首先用随机数生成函数产生“指令”序列,然后将指令序列变换成相应的页地址流,再计算不同算法下的命中率。

2.2.2 通过随机数产生一个指令序列,共产生400条。

其中50%的指令是顺序执行的,且25%的指令分布在前半部分地址空间,25%的指令分布在后半部分地址空间。

2.2.3 将指令地址流变换成页地址流2.2.4 循环运行,使用户内存容量从4到40,。

计算每个内存容量下不同页面置换算法的命中率。

3、算法及数据结构3.1算法的总体思想(流程)struct Pro{int num,time;};int a[total_instruction];int page[N];//调用函数int Search(int e,Pro *page1 ){Pro *page=new Pro[N];page=page1;for(int i=0;i<N;i++){if(e==page[i].num)return i;}return -1;}void Input(Pro p[total_instruction]){int m,i,m1,m2;srand((unsigned int )time(NULL));m=rand()%400;for(i=0;i<total_instruction;) //产生指令队列{if(m<0||m>399){printf("When i==%d,Error,m==%d\n",i,m);exit(0);}a[i]=m; //任选一指令访问点ma[i+1]=a[i]+1;a[i+2]=a[i]+2; //顺序执行两条指令m1=rand( )%m; //执行前地址指令m1a[i+3]=m1;a[i+4]=m1+1;a[i+5]=m1 + 2;//顺序执行两条指令m2 = rand()%(157-m1)+m1+3;a[i+6]=m2;if( (m2+2) > 159 ){a[i+7] = m2+1;i +=8;}else{a[i+7] = m2+1;a[i+8] = m2+2;i = i+9;}m = rand()%m2;}//forfor(i=0;i<total_instruction;i++) //将指令序列变换成页地址流{p[i].num=a[i]/10;p[i].time = 0;}}3.2先进先出算法(FIFO)模块3.2.1 功能根据页地址流,采用先进先出的算法进行页面置换。

请求页式管理的页面置换算法

请求页式管理的页面置换算法

实验报告课程:操作系统班级:成绩:指导教师:实验密级:预习程度:仪器组次:必修/选修:姓名:学号:实验日期:实验时间:实验序号:实验名称:访问实验二请求页式管理中的置换算法实验目的与要求:1.采用FIFO〔先进先出〕置换算法,发生缺页中断时,给出相应的字地址及页号,计算缺页中断率。

2.采用LFU〔最不经常使用〕置换算法,发生缺页中断时,给出相应的字地址及页号,计算缺页中断率。

实验仪器:名称型号数量微机1一、实验内容1.假设有一个用户进程P的地址空间为n〔n=60〕页,系统已在内存中给该进程分配有m〔m<n,m=8〕个页面,且该进程的第0、5、6页〔p0、p5、p6〕已经装入内存,页长为1K。

根据进程访问的字地址序列,采用不同的置换算法,分别计算缺页中断率。

2.进程依次要访问的字地址序列〔访问串〕,在0~1024*n-1〔0~61439〕中模拟随机发生,访问序列的随机生成规那么为:50%的字地址前向顺序增长,25%的字地址均匀分布在前地址〔低地址〕局部,25%的字地址均匀分布在后地址〔高地址〕局部,为了减少模拟次数,前向顺序递增产生的字地址如小于1024*n-51360927〕那么自动加512。

模拟访问串长度为100。

以n=60为例,字地址序列〔访问串〕的随机生成方法如下:〔1〕在[0,61439]之间随机产生起始字地址,当前访问的字地址记为k;〔2〕前向顺序递增产生的字地址为 k+1+512;〔3〕前地址〔低地址〕在[0,k-1]内随机产生;〔4〕后地址〔高地址〕在[k+1,61439]内随机产生;〔5〕重复顺序递增、前地址区间随机产生、后地址区间随机产生的过程,概率分别为:50%、25%、25%。

二、实验要求1.采用FIFO〔先进先出〕置换算法,发生缺页中断时,给出相应的字地址及页号,计算缺页中断率。

2.采用LFU〔最不经常使用〕置换算法,发生缺页中断时,给出相应的字地址及页号,计算缺页中断率。

请求页式存储管理中常用页面置换算法模拟

请求页式存储管理中常用页面置换算法模拟

信息工程学院实验报告课程名称:操作系统Array实验项目名称:请求页式存储管理中常用页面置换算法模拟实验时间:班级姓名:学号:一、实验目的:1.了解内存分页管理策略2.掌握调页策略3.掌握一般常用的调度算法4.学会各种存储分配算法的实现方法。

5.了解页面大小和内存实际容量对命中率的影响。

二、实验环境:PC机、windows2000 操作系统、VC++6.0三、实验要求:本实验要求4学时完成。

1.采用页式分配存储方案,通过分别计算不同算法的命中率来比较算法的优劣,同时也考虑页面大小及内存实际容量对命中率的影响;2.实现OPT 算法 (最优置换算法)、LRU 算法 (Least Recently)、 FIFO 算法 (First IN FirstOut)的模拟;3.会使用某种编程语言。

实验前应复习实验中所涉及的理论知识和算法,针对实验要求完成基本代码编写、实验中认真调试所编代码并进行必要的测试、记录并分析实验结果。

实验后认真书写符合规范格式的实验报告,按时上交。

四、实验内容和步骤:1.编写程序,实现请求页式存储管理中常用页面置换算法LRU算法的模拟。

要求屏幕显示LRU算法的性能分析表、缺页中断次数以及缺页率。

2.在上机环境中输入程序,调试,编译。

3.设计输入数据,写出程序的执行结果。

4.根据具体实验要求,填写好实验报告。

五、实验结果及分析:实验结果截图如下:利用一个特殊的栈来保存当前使用的各个页面的页面号。

当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶。

因此,栈顶始终是最新被访问页面的编号,栈底是最近最久未被使用的页面号。

当访问第5个数据“5”时发生了缺页,此时1是最近最久未被访问的页,应将它置换出去。

同理可得,调入队列为:1 2 3 4 5 6 7 1 3 2 0 5,缺页次数为12次,缺页率为80%。

六、实验心得:本次实验实现了对请求页式存储管理中常用页面置换算法LRU算法的模拟。

计算机操作系统页面置换算法模拟

计算机操作系统页面置换算法模拟

《计算机操作系统》课外实践报告题目:页面置换算法模拟班级: 13级物联网工程一班姓名:王铎学号: 130911044指导老师: 王蕾设计时间: 2014.6一、实验目标:通过设计请求页面存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页面存储管理的页面置换算法。

二、实验要求1通过随机数产生一个指令序列 共320条指令。

指令的地址按下述原则生成50%的指令是顺序执行的25%的指令是均匀分布在前地址部分25%的指令是均匀分布在地址部分。

2将指令序列换成为页地址流。

3计算并输出下述各种算法在不同内存容量下的命中率。

(1)先进先出的算法 FIFO(2)最近最少使用算法 LRU(3)最近最不经常使用算法 NUR三.实践内容简要描述1、实践环境windows XP/7,visual C++ 6.02、算法思路与算法原理2.1、先进先出算法(FIFO):该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。

该算法实现简单,只需要把一个进程已调入内存的页面,按先后次序连接成一个队列,并设置一个指针,成为替换指针,使它总是指向最老的页面。

2.2、最近最久未使用页面置换算法(LRU):算法的基本思想:当需要淘汰某一页时,选择离当前时间最近一段时间内最久没有使用过的页先淘汰。

该算法的出发点是,如果某页被访问了,则它可能马上还被访问。

或者反过来说,如果某页长时间未被访问,则它在最近一段时间不会被访问。

3概要设计3.1 总体设计框图4系统流程图图4.1详细设计框图图4.2为置换方法的流程图5代码分析结果5.1 数据结构int m, int need[],int n, result[10][20],int state[],int count1[];5.2 FIFO具体函数及设计实现FIFO流程图FIFO函数实现void FIFO(int m, int need[],int n) //m分配物理页面大小,n需要页面数组的最大值{int p=0; //当前请求的页面int del=0; //步数int count1[20];double count=0; //缺页数double que=0; //缺页率int result[10][20]; //结果表for(int i =0;i<=m;i++)for(int j=0;j<=n;j++){result[i][j]=-1;count1[j]=-1;}while(n>=p){int k=need[p];if(p>0){for(int i=0;i<=m;i++){result[i][p]=result[i][p-1];}}int f1=0;//首先看是否有空位置或者已经存在请求的页面for(int i =0;i<=m;i++){if(result[i][p]==-1){result[i][p]=k;f1=1;i=m+1;count1[p]=k;count=count+1;p=p+1;}else if(result[i][p]==k){f1=1;p=p+1;i=m+1;}}if(f1==1) continue;//这里发生替换result[del][p]=k;count1[p]=k;count=count+1;p=p+1;del=(del+1)%(m+1);}cout<<"*******************FIFO过程如下表************************"<<endl; for(int t3=0;t3<=n;t3++)//输出原来的页面cout<<need[t3]<<" ";cout<<endl;for(int t0 =0;t0<=m;t0++)//判断页表是否填满{for(int t1=0;t1<=n;t1++){if(result[t0][t1]!=-1)cout<<result[t0][t1]<<" ";else cout<<" "<<" ";}cout<<endl;}for(int j1=0;j1<=n;j1++)//对于缺页的打×,否则打√{if(count1[j1]!=-1)cout<<"×";else cout<<"√";}cout<<endl;que=count/(n+1);//统计缺页次数和缺页率cout<<"缺页次数为:"<<count<<endl;cout<<"缺页率"<<count<<"/"<<n+1<<"="<<que<<endl;cout<<"**************************************************"<<endl;}5.3LRU具体函数及设计实现LRU流程图LRU函数实现void LRU(int m, int need[],int n){m++;n++;int i, j, min, num = 1, k, flag;int state[10], count[20], hsive[10];int result[10][20];memset(state, 0, sizeof(state));//初始化内存空间,给三个数组分配内存memset(count, -1, sizeof(count));memset(hsive, -1, sizeof(hsive));memset(result, -1, sizeof(result));for(i = 0; i < n; i++)//将need数组值赋给resultresult[0][i] = need[i];cout<<"*****************LRU过程如下表*********************"<<endl;for(i = 0; i < n; i++){flag = 0;//标志位,如果页面和页表内的熄灯则赋值for(j = 1; j < num; j++){if(result[0][i] == hsive[j]){flag = 1;state[j] = -1;break;}}if(flag == 0)//替换{if(num <= m)hsive[num] = result[0][i];else{min = -1;for(j = 1; j <= m; j++){if(state[j] > min){k = j;min = state[j];}}hsive[k] = result[0][i];state[k] = -1;}count[i] = 1;num++;}for(j = 1; j <= m; j++){result[j][i] = hsive[j];state[j]++;}}for(j = 0; j <= m; j++)//输入个页面替换情况{for(i = 0; i < n; i++){if(result[j][i] == -1)cout << " ";elsecout << result[j][i] << " ";}cout << endl;}for(i = 0; i < n; i++){if(count[i] != -1)cout<<"×";elsecout<<"√";}cout << endl;//统计各页面缺页次数和缺页率cout << "缺页次数为:" << num - 1 << endl;cout << "缺页率" << num - 1 << "/"<<n << "=" << double(num - 1) / n <<endl;cout<<"**************************************************"<<endl; }主方法int main(){cout<<" *********************************************"<<endl;cout<<" * 页式存储管理*"<<endl;cout<<" ********************************************* "<<endl;int m;int n=0;int choose=2;int need[20];char flag;while(1){cout<<"指定内存分配页面数:";while (flag<'0'||flag>'9'){cin>>flag;}m=flag-'0'-1;flag=' ';cout<<"请选择页面序列产生方式:"<<endl;cout<<" (0)手动输入"<<endl;cout<<" (1)随机产生"<<endl;while (flag<'0'||flag>'1'){cin>>flag;}choose =flag-'0';flag=' ';if(choose==0){cout<<"输入页面走向!以s结尾"<<endl;while(1){while ((flag<'0'||flag>'9')&&flag!='s'){cin>>flag;}if(flag=='s') break;need[n]=flag-'0';flag=' ';n=n+1;}flag=' ';n=n-1;}else {cout<<"随机产生的页面个数:";cin>>n;n=n-1;for(int i=0;i<=n;i++){need[i]=rand()%10;}}system("cls");cout<<"选择页面置换算法:"<<endl;cout<<"0-FIFO 1-LRU"<<endl;while (flag<'0'||flag>'1'){cin>>flag;}choose =flag-'0';flag=' ';if(choose==0){FIFO(m, need,n);}else {LRU(m, need,n);}cout<<"输入Y/y可以看另外一种置换算法的执行过程"<<endl;cin>>flag;if(flag=='Y'||flag=='y'){system("cls");if(choose==0) LRU(m, need,n);else FIFO(m, need,n);}else flag=' ';cout<<"输入N/n退出否则输入任意键继续"<<endl;cin>>flag;if(flag=='N'||flag=='n') break;else{system("cls");flag=' ';}}return 0;}5.4调用关系图6测试6.1进入界面及产生页面走向运行结果如下图6.1 进入管理界面图6.2产生页面走向6.2FIFO算法及查看结果图6.3选择FIFO算法结果6.3LRU算法及查看结果图6.4选择LRU结果6.4继续进入主界面及产生页面走向图6.5按y继续回到主界面设置页面为46.5调度算法及结果图6.6选择LRU算法结果图6.7选择FIFO算法结果7 总结与体会通过这次实验,我基本了解了页面置换算法的基本设置与要求,懂得了先进先出算法(FIFO)、最近最久未使用页面置换算法(LRU)的基本编程及算法原理。

操作系统——模拟页面置换算法(FIFO——先入先出、LRU——最近最少使用、LFU——最近。。。

操作系统——模拟页面置换算法(FIFO——先入先出、LRU——最近最少使用、LFU——最近。。。

操作系统——模拟页⾯置换算法(FIFO——先⼊先出、LRU——最近最少使⽤、LFU——最近。

操作系统——模拟页⾯置换算法(FIFO——先⼊先出、LRU——最近最少使⽤、LFU——最近最不常使⽤),计算置换率(包含程序框图)导语:1. FIFO页⾯置换算法:最简单的页⾯置换算法。

这种算法的基本思想是:当需要淘汰⼀个页⾯时,总是选择驻留主存时间最长的页⾯进⾏淘汰,即先进⼊主存的页⾯先淘汰。

(看时间)2. LRU页⾯置换算法:最近最少使⽤,简单来说就是将数据块中,每次使⽤过的数据放在数据块的最前端,然后将存在的时间最长的,也就是数据块的末端的数据置换掉。

(看时间)3. LFU页⾯置换算法:近期最少使⽤算法,选择近期最少访问的页⾯作为被替换的页⾯,如果⼀个数据在最近⼀段时间内使⽤次数很少,那么在将来⼀段时间内被使⽤的可能性也很⼩。

(看次数)4. 置换率与与缺页率不同。

置换率⽤置换次数算,缺页率⽤缺页中断次数算。

FIFO页⾯置换算法:Linux效果图(采⽤UOS + VScode + g++)程序框图C++代码(FIFO):#include<iostream>using namespace std;static int mnum;//物理块数static int pnum;//页⾯⾛向static int count=0;//页⾯置换次数static int *analogblock;//模拟物理块static int *block;//物理块static int *process;//随机页⾯访问序列int judge(int a[],int n,int x) //判断数组中是否已有x,若有返回其下标值,没有则返回-1 {int i;for (i=0;i<n;i++)if(x==a[i])return i;return -1;}void replace(int y,int mnum,int x)//⽤于物理块页⾯置换,y是⽤来置换的页⾯,x是被置换的页⾯ {int i;for (i=0;i<mnum;i++)if(x==block[i])block[i]=y;}int main() {int i;int maxanalogblock=-1;//模仿队列的定义int x;cout<<"请输⼊页框⼤⼩物理块数:\n";cin>>mnum;if(mnum>999999) {cout<<"输⼊超出控制⼤⼩!"<<endl;return 0;}cout<<"⾃动⽣成的内存块需求序列个数:\n";cin>>pnum;if(pnum>999999) {cout<<"输⼊超出控制⼤⼩!"<<endl;return 0;}analogblock=new int[mnum];block=new int[mnum];process=new int[pnum];for (i=0;i<mnum;i++) analogblock[i]=-1;for (i=0;i<mnum;i++) block[i]=-1;///////////////////////随机产⽣页⾯⾛向序列cout<<"产⽣随机序列如下:\n";srand( (unsigned)time( NULL ) );//以time函数值(即当前时间)作为种⼦数,保证两次产⽣序列的随机性for (i=0; i<pnum; i++) {process[i] = rand()%10;cout<<process[i]<<" ";}cout<<endl;//////////////////////cout<<"先进先出(FIFO)页⾯置换算法,结果: \n\n";//////////////////////for (x=0;x<pnum;x++) //⾃动读数 {//读⼀个序列号,输出当前数组元素cout<<"真实物理块情况:";for (i=0;i<mnum;i++) {if(block[i]!=-1)cout<<block[i]<<" ";}cout<<"模拟物理块情况:";for (i=0;i<mnum;i++) {if(analogblock[i]!=-1)cout<<analogblock[i]<<" ";}//////////////////////////maxanalogblock++;//读数后maxanalogblock⾃动+1if(maxanalogblock<mnum) //若在物理块范围内 {if(judge(analogblock,mnum,process[x])==-1)//若数组中不存在待插⼊元素 {analogblock[maxanalogblock]=process[x];//新元素从尾部插⼊block[maxanalogblock]=process[x];//新元素从尾部插⼊cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 缺页中断调⼊页⾯"<<process[x]<<endl;} else //若数组中存在待插⼊元素 {maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock值cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 已存在直接访问"<<endl;}} else //超过物理块数的元素 {if(judge(analogblock,mnum,process[x])==-1)//若数组中不存在待插⼊元素 {//队列法插⼊(尾部元素出,新元素从头部⼊)cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 缺页中断页⾯"<<process[x]<<"置换出页⾯"<<analogblock[0]<<endl; replace(process[x],mnum,analogblock[0]);//置换物理块中页⾯for (i=0;i<mnum-1;i++)LRU 页⾯置换算法:Linux 效果图(采⽤UOS + VScode + g++)程序框图C++代码(LRU): analogblock[i]=analogblock[i+1];analogblock[mnum-1]=process[x];//////////////////maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock 值count++;} else //若数组中存在待插⼊元素 {maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock 值cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 已存在 直接访问"<<endl;}}}//读⼀个序列号,输出当前数组元素cout<<"真实物理块情况:";for (i=0;i<mnum;i++) {if(block[i]!=-1) cout<<block[i]<<" ";}cout<<"模拟物理块情况:";for (i=0;i<mnum;i++) {if(analogblock[i]!=-1)cout<<analogblock[i]<<" ";}cout<<endl<<"页⾯换算次数为:"<<count<<endl;cout<<"置换率为:"<<(float)count/pnum<<endl;return 0;}//g++ test71.cpp -o test71 -lpthread&&./test71#include<iostream>using namespace std;static int mnum;//物理块数static int pnum;//页⾯⾛向static int count=0;//页⾯置换次数static int *analogblock;//模拟物理块static int *block;//物理块static int *process;//随机页⾯访问序列int judge(int a[],int n,int x) //判断数组中是否已有x ,若有返回其下标值,没有则返回-1 {int i;for (i=0;i<n;i++)if(x==a[i])return i;return -1;}void replace(int y,int mnum,int x)//⽤于物理块页⾯置换,y是⽤来置换的页⾯,x是被置换的页⾯ { int i;for (i=0;i<mnum;i++)if(x==block[i])block[i]=y;}void move(int a[],int n,int i) //移动下标为i的元素到尾部 {int j;int m=a[i];for (j=i;j<n-1;j++)a[j]=a[j+1];a[n-1]=m;}int main() {int i;int maxanalogblock=-1;//模仿栈的定义int x;cout<<"请输⼊页框⼤⼩物理块数:\n";cin>>mnum;if(mnum>999999) {cout<<"输⼊超出控制⼤⼩!"<<endl;return 0;}cout<<"⾃动⽣成的内存块需求序列个数:\n";cin>>pnum;if(pnum>999999) {cout<<"输⼊超出控制⼤⼩!"<<endl;return 0;}analogblock=new int[mnum];block=new int[mnum];process=new int[pnum];for (i=0;i<mnum;i++) analogblock[i]=-1;///////////////////////随机产⽣页⾯⾛向序列cout<<"产⽣随机序列如下:\n";srand( (unsigned)time( NULL ) );//以time函数值(即当前时间)作为种⼦数,保证两次产⽣序列的随机性for (i=0; i<pnum; i++) {process[i] = rand()%10;cout<<process[i]<<" ";}cout<<endl;//////////////////////cout<<"最近最少使⽤(LRU)页⾯置换算法,结果: \n\n";//////////////////////for (x=0;x<pnum;x++) //⾃动读数 {//读⼀个序列号,输出当前数组元素cout<<"真实物理块情况:";for (i=0;i<mnum;i++) {if(block[i]!=-1)cout<<block[i]<<" ";}cout<<"模拟物理块情况:";for (i=0;i<mnum;i++) {if(analogblock[i]!=-1)cout<<analogblock[i]<<" ";}//////////////////////////maxanalogblock++;//读数后maxanalogblock⾃动+1LFU 页⾯置换算法:Linux 效果图(采⽤UOS + VScode + g++)程序框图 if(maxanalogblock<mnum) //若在物理块范围内 {if(judge(analogblock,mnum,process[x])==-1)//若数组中不存在待插⼊元素 {analogblock[maxanalogblock]=process[x];//新元素从尾部插⼊block[maxanalogblock]=process[x];//新元素从尾部插⼊cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 缺页中断 调⼊页⾯"<<process[x]<<endl;} else //若数组中存在待插⼊元素 {move(analogblock,maxanalogblock,judge(analogblock,mnum,process[x]));//移动下标为i 的元素到尾部maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock 值cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 已存在 直接访问"<<endl;}} else //超过物理块数的元素 {if(judge(analogblock,mnum,process[x])==-1)//若数组中不存在待插⼊元素 {//栈法插⼊(第⼀个元素出,后⾯元素前移,新元素从尾部⼊)cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 缺页中断 页⾯"<<process[x]<<"置换出页⾯"<<analogblock[0]<<endl; replace(process[x],mnum,analogblock[0]);//物理块中页⾯置换for (i=0;i<mnum-1;i++)analogblock[i]=analogblock[i+1];analogblock[mnum-1]=process[x];//////////////////maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock 值count++;} else //若数组中存在待插⼊元素 {move(analogblock,mnum,judge(analogblock,mnum,process[x]));//移动下标为i 的元素到尾部maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock 值cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 已存在 直接访问"<<endl;}}}//读⼀个序列号,输出当前数组元素cout<<"真实物理块情况:";for (i=0;i<mnum;i++) {if(block[i]!=-1)cout<<block[i]<<" ";}cout<<"模拟物理块情况:";for (i=0;i<mnum;i++) {if(analogblock[i]!=-1)cout<<analogblock[i]<<" ";}cout<<endl<<"页⾯换算次数为:"<<count<<endl;cout<<"置换率为:"<<(float)count/pnum<<endl;return 0;}//g++ test72.cpp -o test72 -lpthread&&./test72C++代码(LFU):#include<iostream>using namespace std;static int mnum;//物理块数static int pnum;//页⾯⾛向static int count=0;//页⾯置换次数static int **analogblock;//模拟物理块static int *block;//物理块static int *process;//随机页⾯访问序列int judge(int *a[],int n,int x) //判断数组中是否已有x,若有返回其下标值,没有则返回-1 {int i;for (i=0;i<n;i++)if(x==a[i][0])return i;return -1;}void replace(int y,int mnum,int x)//⽤于物理块页⾯置换,y是⽤来置换的页⾯,x是被置换的页⾯ { int i;for (i=0;i<mnum;i++)if(x==block[i])block[i]=y;}void move(int *a[],int n,int i) //移动下标为i的元素,⽐较访问次数次多少进⾏前进 {int j;int m=a[i][0];int m2=a[i][1];for (j=i;j<n-1;j++) {if(m2>=a[j+1][1]) {a[j][0]=a[j+1][0];a[j][1]=a[j+1][1];a[j+1][0]=m;a[j+1][1]=m2;}}}int main() {int i;int maxanalogblock=-1;//模仿栈的定义int x;//动态数组初始化cout<<"请输⼊页框⼤⼩物理块数:\n";cin>>mnum;if(mnum>999999) {cout<<"输⼊超出控制⼤⼩!"<<endl;return 0;}cout<<"⾃动⽣成的内存块需求序列个数:\n";cin>>pnum;if(pnum>999999) {cout<<"输⼊超出控制⼤⼩!"<<endl;return 0;}analogblock=(int**) (new int[mnum]);block=new int[mnum];process=new int[pnum];for (i=0;i<mnum;i++) analogblock[i]=(int*) new int[2];//⽤于保存页⾯号和访问次数for (i = 0; i < mnum; i++) {analogblock[i][0]=-1;analogblock[i][1]=0;}///////////////////////随机产⽣页⾯⾛向序列cout<<"产⽣随机序列如下:\n";srand( (unsigned)time( NULL ) );//以time函数值(即当前时间)作为种⼦数,保证两次产⽣序列的随机性for (i=0; i<pnum; i++) {process[i] = rand()%10;cout<<process[i]<<" ";}cout<<endl;//////////////////////cout<<"最近最不常使⽤(LFU)页⾯置换算法,结果: \n\n";//////////////////////for (x=0;x<pnum;x++) //⾃动读数 {//读⼀个序列号,输出当前数组元素cout<<"真实物理块情况:";for (i=0;i<mnum;i++) {if(block[i]!=-1)cout<<block[i]<<" ";}cout<<"模拟物理块情况:";for (i=0;i<mnum;i++) {if(analogblock[i][0]!=-1)cout<<analogblock[i][0]<<" ";//<<"访问次数"<<analogblock[i][1]<<" "}//////////////////////////maxanalogblock++;//读数后maxanalogblock⾃动+1if(maxanalogblock<mnum) //若在物理块范围内 {if(judge(analogblock,mnum,process[x])==-1)//若数组中不存在待插⼊元素 {analogblock[0][0]=process[x];//新元素从头部插⼊analogblock[0][1]=1;block[maxanalogblock]=process[x];//新元素从尾部插⼊move(analogblock,mnum,0);//移动下标为i的元素到相同访问次数页⾯的顶部cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 缺页中断调⼊页⾯"<<process[x]<<endl;} else //若数组中存在待插⼊元素 {// move(analogblock,maxanalogblock,judge(analogblock,mnum,process[x]));//移动下标为i的元素到尾部analogblock[judge(analogblock,mnum,process[x])][1]++;move(analogblock,mnum,judge(analogblock,mnum,process[x]));//移动下标为i的元素到相同访问次数页⾯的顶部maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock值cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 已存在直接访问"<<endl;}} else //超过物理块数的元素 {if(judge(analogblock,mnum,process[x])==-1)//若数组中不存在待插⼊元素 {//栈法插⼊(新元素从头部⼊,替换掉头部)cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 缺页中断页⾯"<<process[x]<<"置换出页⾯"<<analogblock[0][0]<<endl; replace(process[x],mnum,analogblock[0][0]);//物理块中页⾯置换analogblock[0][0]=process[x];analogblock[0][1]=1;move(analogblock,mnum,0);//移动下标为i的元素相同访问次数页⾯的顶部//////////////////maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock值count++;} else //若数组中存在待插⼊元素 {analogblock[judge(analogblock,mnum,process[x])][1]++;move(analogblock,mnum,judge(analogblock,mnum,process[x]));//移动下标为i的元素到相同访问次数页⾯的顶部maxanalogblock--;//因为没有插⼊新元素,回滚maxanalogblock值cout<<" 第"<<x+1<<"次访问,页⾯"<<process[x]<<" 已存在直接访问"<<endl; }}}//读⼀个序列号,输出当前数组元素cout<<"真实物理块情况:";for (i=0;i<mnum;i++) {if(block[i]!=-1)cout<<block[i]<<" ";}cout<<"模拟物理块情况:";for (i=0;i<mnum;i++) {if(analogblock[i][0]!=-1)cout<<analogblock[i][0]<<" ";}cout<<endl<<"页⾯换算次数为:"<<count<<endl;cout<<"置换率为:"<<(float)count/pnum<<endl;return 0;}//g++ test73.cpp -o test73 -lpthread&&./test73。

请求页式管理中的置换算法

请求页式管理中的置换算法

请求页式管理中的置换算法页式管理是计算机内存管理的一种方式,它利用虚拟内存和分页技术使得操作系统可以在有限的物理内存下运行更多的进程。

在页式存储管理中,操作系统将物理内存分成若干个固定的大小的块,称为物理块,同时将进程分成若干个大小相等的块,称为页面。

当一个进程需要访问某个页面时,操作系统就将页面调入物理块中,若所有物理块都被占满,则需要选择一个物理块将其替换成即将调入的页面,这就需要使用到置换算法。

常见的置换算法有如下几种:1. 先进先出算法(FIFO)该算法是最简单的、最易实现的一种页面置换算法。

其原理是将先进入内存的页面优先替换出去。

使用一个先进先出的队列来维护物理块的使用情况,每次选择队列头的页面进行置换。

因此该算法的缺点就是无法考虑页面替换的实际使用情况。

2. 最近最少使用算法(LRU)该算法会将最近未被使用的页面优先置换出去,即在内存中驻留时间最长的页面最不容易被替换出去。

其难点在于如何确定何时页面被使用过。

可以使用栈或者链表来实现。

3. 最不常用算法(LFU)该算法会将内存中使用次数最少的页面优先置换出去,即在内存中使用次数最少的页面最容易被替换出去。

为实现该算法,需要维护每个页面的使用次数。

4. 时钟算法(Clock)该算法是一种Clock页面置换算法,在物理块使用情况时采用了一个环形链表的结构。

每个页面都有一个标志位,若该位为1,则说明该页面在当前的一轮中被使用过,同时将该位变为0;若该位为0,则说明该页面未被使用过,这时候会考虑是否将该页面替换出去。

5. 二次机会算法(Second chance)该算法对时钟算法进行了改进,增加了一个修改位,表明是否被修改过。

每次选择的是位0(未被使用/未被修改)或者1(未被使用/被修改)的页面,如果选择到的是1则把修改位清零,并转化为0重新加入内存块队列。

以上是常见的五种页面置换算法,不同的算法有各自的优缺点,需要根据内存管理的需要、机器性能和系统配置来选择合适的算法来实现。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

请求页式存储管理中常用页面置换算法模拟-标准化文件发布号:(9456-EUATWK-MWUB-WUNN-INNUL-DDQTY-KII信息工程学院实验报告课程名称:操作系统Array实验项目名称:请求页式存储管理中常用页面置换算法模拟实验时间:班级姓名:学号:一、实验目的:1.了解内存分页管理策略2.掌握调页策略3.掌握一般常用的调度算法4.学会各种存储分配算法的实现方法。

5.了解页面大小和内存实际容量对命中率的影响。

二、实验环境:PC机、windows2000 操作系统、VC++6.0三、实验要求:本实验要求4学时完成。

1.采用页式分配存储方案,通过分别计算不同算法的命中率来比较算法的优劣,同时也考虑页面大小及内存实际容量对命中率的影响;2.实现OPT 算法 (最优置换算法)、LRU 算法 (Least Recently)、 FIFO 算法(First IN First Out)的模拟;3.会使用某种编程语言。

实验前应复习实验中所涉及的理论知识和算法,针对实验要求完成基本代码编写、实验中认真调试所编代码并进行必要的测试、记录并分析实验结果。

实验后认真书写符合规范格式的实验报告,按时上交。

四、实验内容和步骤:1.编写程序,实现请求页式存储管理中常用页面置换算法LRU算法的模拟。

要求屏幕显示LRU算法的性能分析表、缺页中断次数以及缺页率。

2.在上机环境中输入程序,调试,编译。

3.设计输入数据,写出程序的执行结果。

4.根据具体实验要求,填写好实验报告。

五、实验结果及分析:实验结果截图如下:利用一个特殊的栈来保存当前使用的各个页面的页面号。

当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶。

因此,栈顶始终是最新被访问页面的编号,栈底是最近最久未被使用的页面号。

当访问第5个数据“5”时发生了缺页,此时1是最近最久未被访问的页,应将它置换出去。

同理可得,调入队列为:1 2 3 4 5 6 7 1 3 2 0 5,缺页次数为12次,缺页率为80%。

六、实验心得:本次实验实现了对请求页式存储管理中常用页面置换算法LRU算法的模拟。

通过实验,我对内存分页管理策略有了更多的了解。

最近最久未使用(LRU)置换算法的替换规则:是根据页面调入内存后的使用情况来进行决策的。

该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间,当需淘汰一个页面的时候选择现有页面中其时间值最大的进行淘汰。

最佳置换算法的替换规则:其所选择的被淘汰页面,将是以后永不使用的或许是在最长(未来)时间内不再被访问的页面。

先进先出(FIFO)页面置换算法的替换规则:该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。

该算法实现简单只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。

三种替换算法的命中率由高到底排列OPT>LRU>FIFO。

本次的程序是在网上查找的相关代码然后自己进行修改,先自己仔细地研读了这段代码,在这过程中我对C++代码编写有了更深的了解。

总之,本次实验使我明白要学会把课堂上的理论应用到实际操作中。

我需要在今后熟练掌握课堂上的理论基础,只有坚实的基础,才能在实际操作中更得心应手。

附录:#include "iostream.h"#include <iomanip.h>const int DataMax=100;const int BlockNum = 10;int DataShow[BlockNum][DataMax]; // 用于存储要显示的数组bool DataShowEnable[BlockNum][DataMax]; // 用于存储数组中的数据是否需要显示int Data[DataMax]; // 保存数据int Block[BlockNum]; // 物理块int count[BlockNum]; // 计数器int N ; // 页面个数int M;//最小物理块数int ChangeTimes;void DataInput(); // 输入数据的函数void DataOutput();void LRU(); // LRU函数///*int main(int argc, char* argv[]){DataInput();// DataInput();LRU();return 0;}//*/void DataInput(){cout<<"请输入最小物理块数:";cin>>M;while(M > BlockNum) // 大于数据个数{cout<<"物理块数超过预定值,请重新输入:";cin>>M;}cout<<"请输入页面的个数:";cin>>N;while(N > DataMax) // 大于数据个数{cout<<"页面个数超过预定值,请重新输入:";cin>>N;}cout<<"请输入页面访问序列:"<<endl;for(int i=0;i<N;i++)cin>>Data[i];}void DataOutput(){int i,j;for(i=0;i<N;i++) // 对所有数据操作{cout<<Data[i]<<””;}cout<<"\n--------------------------------"<<endl;for(j=0;j<M;j++){cout<<" ";for(i=0;i<N;i++) // 对所有数据操作{if( DataShowEnable[j][i] )cout<<DataShow[j][i]<<" | ";elsecout<<" | ";}cout<<endl;}cout<<"\n缺页次数: "<<ChangeTimes<<endl;cout<<"缺页率: "<<ChangeTimes*100/N<<"%"<<endl;}void LRU(){int i,j;bool find;int point;int temp; // 临时变量ChangeTimes = 0;for(j=0;j<M;j++)for(i=0;i<N;i++)DataShowEnable[j][i] = false; // 初始化为false,表示没有要显示的数据 for(i=0;i<M;i++){count[i] = 0 ;}for(i=0;i<N;i++) // 对有所数据操作{// 增加countfor(j=0;j<M;j++)count[j]++;find = false; // 表示块中有没有该数据for(j=0;j<M;j++){if( Block[j] == Data[i] ){count[j] = 0;find = true;}}if( find ) continue; // 块中有该数据,判断下一个数据// 块中没有该数据ChangeTimes++; // 缺页次数++if( (i+1) > M ) // 因为i是从0开始记,而BlockNum指的是个数,从1开始,所以i+1{//获得要替换的块指针temp = 0;for(j=0;j<M;j++){if( temp < count[j] ){temp = count[j];point = j; // 获得离的最远的指针}}}else point = i;// 替换Block[point] = Data[i];count[point] = 0;// 保存要显示的数据for(j=0;j<M;j++){DataShow[j][i] = Block[j];DataShowEnable[i<M(j<=ij:i):j][i] = true; // 设置显示数据}}// 输出信息cout<<endl;cout<<"内存状态:\n"<<"--------------------------------"<< endl;DataOutput();}。

相关文档
最新文档