页面置换实习报告.docx
《页面置换实习报告.docx》由会员分享,可在线阅读,更多相关《页面置换实习报告.docx(18页珍藏版)》请在冰豆网上搜索。
页面置换实习报告
实习报告----页面置换算法
一、设计目的:
加深对请求页式存储管理实现原理的理解,掌握页面置换算法。
二、设计内容
设计一个进程,可以实现用户可以为程序指定内存块数,自由设置程序的页面访问顺序,还可以在OPT、FIFO和LRU算法自由选择一个,并能观看到页面置换过程。
三、开发环境
windows环境,VC6.0平台。
四、分析设计
<一>实验原理
为提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行:
一个进程只需将其中一部分(段或页)调入内存变可运行;还支持请求调页的存储管理方式。
当进程在进行中需要访问某部分程序和数据时,发现其所在的页面不在内存,就立即提出请求(向CPU发出中断),由系统将其所需页面调入内存。
这种页面调入方式叫做请求调页。
当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。
该程序通过查找页表,得到该页所在外存的物理块号。
如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。
如果内存已满,则需按照某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。
利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。
整个页面的调入程序对用户是透明的。
下面把我所用到的页面置换算法:
最佳置换算法(OPT)、先进先出页面置换算法(FIFO)、最近最少使用页面置换算法(LRU),并对这些原理进行描述:
最佳置换算法(OPT)原理:
选择淘汰的页面,将是以后永不使用的,或者是最长(未来)时间内不再被访问的页面。
采用最佳置换算法,通常课保证最低缺页率。
先进先出页面置换算法(FIFO)原理:
该算法总是先淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
最近最少使用页面置换算法(LRU)原理:
由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似。
选择最近最久未使用的页面予以淘汰,该算法赋予每个页面一个访问字段,用来记录一个页面自上次呗访问以来所经历的时间t,当必须淘汰一个页面时,选择现有页面中其t最大的,即最近最少使用页面予以淘汰。
<二>程序结构
我的程序分为三部分:
第一部分:
键盘输入数据作为测试用例
用for循环进行数据的连续输入
第二部分:
算法的实现
算法的实现也分为三部分:
1.算法1---最佳置换算法(OPT)
(1).数据刚入栈,物理块数都为缺页数
(2).超过分配的物理块数,如果有与栈内的数据一致的称为命中数据,并把栈内数据打印出来:
Print(Num),并用一个m=1标记有命中数据
(3)超过分配的物理块数,如果没有与栈内的数据一致的数据,则调用findspace()函数,让栈内的数与后面的数进行比较,如果有相同的数就用pos1[j]记下他们的标号i(j从0开始),如果有一个没有命中,则把此数换出去,而如果物理块都有命中,则比较pos1[j]中那个数最大,把最大的数换出去,因为此时这个数是最长(未来)时间内不再被访问的页面,并且缺页次数++。
(4)计算缺页率并打印出来
2.算法2---先进先出页面置换算法(FIFO):
(1).数据刚入栈,物理块数都为缺页数
(2).超过分配的物理块数,如果有与栈内的数据一致的称为命中数据,并把栈内数据打印出来:
Print(Num),并用一个m=1标记有命中数据
(3)超过分配的物理块数,如果没有与栈内的数据一致的数据,则把先进栈的数换出去,让栈内的数从第二数开始往前移,然后把刚入栈的数据放入栈尾,打印出来,并且缺页次数++。
(4)计算缺页率并打印出来
3.算法3---最近最少使用页面置换算法(LRU):
(1).数据刚入栈,物理块数都为缺页数
(2).超过分配的物理块数,如果有与栈内的数据一致的称为命中数据,并把栈内数据打印出来:
Print(Num),并用一个m=1标记有命中数据
(3)超过分配的物理块数,如果没有与栈内的数据一致的数据,则把先进栈的数换出去,让栈内的数从第二数开始往前移,然后把刚入栈的数据放入栈尾,打印出来,并且缺页次数++。
(4)计算缺页率并打印出来
第三部分:
程序的运行
(1).输入进程物理块数
(2).输入进程页面地址数
(3)输入进程页面地址流,即测试的数据
(4)把置换的结果、缺页次数和缺页率打印到屏幕上
<三>一些全局数据的设置:
先为物理块分配空间,然后在根据用户需求进行输入物理块的大小:
#definepNum100//全局变量
而每种算法都要对缺页次数和缺页次数进行统计,为了方便用户使用和理解,也设置一个全局变量:
intqycs=0;//缺页次数
floatqyl;//缺页率
进程块赋初值,赋予一个空间,方便我们输入空间大小和查看页面置换的命中率与缺页率
charpblock[pNum];
<四>程序流程图:
开始
Y
N
五.运行示例及结果分析
横着看栈,用-1标记数据没有入栈,此时表明有四个物理块(栈)
六、心得与体会
在这两周的计算机操作系统实习中,我学到了很多东西。
不仅对LINUX的终端操作的了解加深了很多,不光是懂得指令的操作,而且明白了以前很多模糊的地方,比如对权限的访问那一部分,以前只知道用
chmodg+w文件名;chmodo-r文件名
这两条指令修改权限,却不知道-rw-rw-rw-是什么意思,通过这次实习,我明白了这是多级访问权限的意思,还有一些类似的指令也是一样。
这次老师还要我们看了fork.cpp的代码,一开始,LINUX里面的代码太多了,找不到,后来用搜索的功能才把fork.cpp找到,发现它在,后来从老师给的资料才知道,fork的功能是复制进程里面的东西,对LINUX进程的创建、内容的复制有了更深层次的了解,包括如何调用线程,父进程和子进程等等。
但是让我感触最深的还是对页面置换算法程序编写的过程。
一开始大家都只是懂得原理,不是很懂得怎么实现,后来我们几个做页面置换的同学就在一起讨论怎么实现题目要求的功能,最后我决定选择堆栈的方法进行页面置换。
在进行FIFO和LRU这两种置换方法的时候,思想很类似,就是发现物理块内的数没有命中的时候,把需要置换的数据移出栈外,让后面的数往前移,并把最新入栈的数据放到栈的最后面,并以此类推。
而OPT算法则不是这样的,刚入栈的时候与前面两种算法一样,但是到后面的时候,在发现栈后第一个数据没有与栈内的数据一致即没有命中数据的时候,则调用findspace()函数,先用栈内的第一数分别与栈外面的数依次进行比较,如果发现第一个一致的,则用数POS1[j](j从0开始)记下那个数的位置,并把标记数K2++,如果没有一致的,则把pos1[]=0,再用相同的方法把第二个数分别与后面的数进行比较。
等栈内的数据比较完了以后,看是否有pos1[j]=0的,如果有,则把此页换出,把栈外第一个数换进来,如果有两个,则把离栈顶最近的数换出,如果没有则比较所有pos1[j]中数,把最大的数的那一页换出,因为此时表明命中的数离栈最远,符合以后永不使用的,或者是最长(未来)时间内不再被访问的页面的原理。
而在此之后如栈的数还是用同样地方法进行比较,老师说这样的话空间花费大,代码需要优化,这也是我要改进的地方。
我发现我还有一个地方不足的是我不是很会用界面来做实习,这也是我将来要努力的方向。
这就是我这次实习的心得和体会。
参考文献:
1、汤子嬴编:
《计算机操作系统》,西安电子科技大学出版社
2、陈智勇编:
《计算机系统结构》,西安电子科技大学出版社
附录、源程序清单
/*页面置换算法性能测试
要求:
1.用户可以为程序指定内存块数
2.用户可以自由设置程序的页面访问顺序
3.用户可在OPT、FIFO和LRU算法选择一个,并能观看到页面置换过程。
*/
#include
#include
#include
#include
#include
#include
#definepNum100//系统为进程分配物理空间
intqycs=0;//缺页次数
charpblock[pNum];//进程块赋初值,方便我们看页面置换的命中率与缺页率
floatqyl;//缺页率
voidjpsr(intymNum,charp[])//由键盘输入n个整数放到p[]数组里面
{
inti;
for(i=0;iscanf("%d",&p[i]);
}
voidPrint(intNum)//打印进程块的内容
{
inti;
for(i=0;iprintf("%3d",pblock[i]);
printf("\n");
}
intfindspace(intm,charym[],intNum,intymNum)//为最佳置换算法(Optimal)寻找该置换的物理块号
{
inti,j,k=0,k2=0,pos1[100],pos2,pos=0;
for(j=0;j//k2是个计数器如果Num块物理块中的某一块地址序列第M位后的元素不会发生命中pos1[该物理块号]的值为零
//发生命中pos1[该物理块号]=该数在序列里的位置
{
for(i=m;i{if(ym[i]==pblock[j])
{
pos1[j]=i;k2++;break;
}
elsepos1[j]=0;
}
}
if(k2==Num)//取pos1数组的最大值舍去
{
pos2=pos1[0];
for(k=1;k{
if(pos2pos=k;
elsepos2=pos1[k];
}
returnpos;
}
else//当分配的物理块中有在后续中不使用的,可以直接舍去语句pos1[j]=0;的作用在此
{
for(pos=0;pos{
if(pos1[pos]==0)returnpos;
}
}
}
voidOptimal(charym[],intNum,intymNum)//最佳置换算法
{
inti,j,m=0,p;
for(j=0;j{
pblock[j]=ym[j];Print(Num);qycs++;
}
for(j=Num;j{
m=0;
for(i=0;iif(ym[j]==pblock[i])//如果有与栈内的数据一致的称为命中数据
{
m=1;Print(Num);break;
}
if(m==0)//没有与栈内的数据一致,缺页次数加1
{
p=findspace(j,ym,Num,ymNum);
pblock[p]=ym[j];
Print(Num);
qycs++;
}
}
qyl=(float)qycs/ymNum;//计算缺页率
printf("|-----------------------------------------------------|\n");
printf("缺页次数为%d\n",qycs);
printf("缺页率为%f\n",qyl);
printf("|-----------------------------------------------------|\n");
}
voidFIFO(charym[],intNum,intymNum)//先进先出算法
{
inti,j,m=0;
qycs=0;//防止多次选择时qycs会累加
for(j=0;j{
pblock[j]=ym[j];Print(Num);qycs++;
}
for(j=Num;j{
m=0;
for(i=0;iif(ym[j]==pblock[i])
{
m=1;Print(Num);break;
}
if(m==0)//没有与栈内的数据一致,缺页次数加1
{
for(i=0;ipblock[i]=pblock[i+1];
pblock[Num-1]=ym[j];
Print(Num);
qycs++;
}
}
qyl=(float)qycs/ymNum;
printf("|-----------------------------------------------------|\n");
printf("缺页次数为%d\n",qycs);
printf("缺页率为%f\n",qyl);
printf("|-----------------------------------------------------|\n");
}
voidLRU(charym[],intNum,intymNum)//最近最久未使用算法
{
intc=0,i,j,m=0;
qycs=0;
for(j=0;j{
pblock[j]=ym[j];Print(Num);qycs++;
}
for(j=Num;j{
m=0;
for(i=0;iif(ym[j]==pblock[i])
{
c=ym[j];
for(i++;i{
pblock[i-1]=pblock[i];
}
pblock[Num-1]=c;Print(Num);
m=1;
printf("\n");
}
if(m==0)
{
for(i=0;ipblock[i]=pblock[i+1];
pblock[Num-1]=ym[j];
Print(Num);
qycs++;
}
}
qyl=(float)qycs/ymNum;
printf("|-----------------------------------------------------|\n");
printf("缺页次数为%d\n",qycs);
printf("缺页率为%f\n",qyl);
printf("|-----------------------------------------------------|\n");
}
voiddisplay1()
{
printf("|>-----------------------------------------------------<|\n");
printf("|>----------作者:
张莉芸学号:
3090717238----------<|\n");
printf("|>----------------
(1)最佳置换算法------------<|\n");
printf("|>----------------
(2)先进先出算法------------<|\n");
printf("|>----------------(3)最近最久未使用算法------------<|\n");
printf("|>----------------(0)退出------------<|\n");
printf("|>-----------------------------------------------------<|\n");
}
voidrun()
{
voiddisplay2(intselect,charym[],intNum,intymNum);
intselect,s2,i,Num,ymNum;
charch;
charym[20];
for(Num=0;Num{
pblock[Num]=-1;
}//进程块赋初值,方便我们看页面置换的命中率与缺页率
printf("\n\n\n\n");
printf("|>-----------------------------------------------------<|\n");
printf("|>----------作者:
张莉芸学号:
3090717238----------<|\n");
printf("|>---------------
(1)键盘输入产生--------------<|\n");
printf("|>---------------(0)退出--------------<|\n");
printf("|>-----------------------------------------------------<|\n");
printf("\n\n\n\n");
printf("输入进程分配的物理块数:
");
scanf("%d",&Num);
printf("输入进程页面地址数(不能超过20):
");
scanf("%d",&ymNum);
printf("请选择产生页面走向序列的方式(选择1或选择0退出):
");
scanf("%d",&select);
switch(select)
{
case1:
jpsr(ymNum,ym);
do{
printf("\n你想选择那种算法?
(请选择1~4,选0退出):
\n");
display1();
printf("选:
");
scanf("%d",&s2);
display2(s2,ym,Num,ymNum);
for(i=0;ipblock[i]=0;
cout<<"要继续吗?
(y/n)";
cin>>ch;
}while(ch=='y');
break;
case0:
break;
}
}
voiddisplay2(intselect,charym[],intNum,intymNum)
{
switch(select)
{
case1:
printf("****************Optimal算法****************\n");Optimal(ym,Num,ymNum);break;
case2:
printf("****************FIFO算法****************\n");FIFO(ym,Num,ymNum);break;
case3:
printf("****************LRU算法****************\n");LRU(ym,Num,ymNum);break;
case0:
run();break;
}
}
voidmain()
{
system("color3f");//改变显示屏的颜色
system("modecon:
cols=140lines=90");
run();//运行结果
}