设计一个虚拟存储区和内存工作区编程序演示下述算法的具体实现过程并计算访问命中率剖析.docx
《设计一个虚拟存储区和内存工作区编程序演示下述算法的具体实现过程并计算访问命中率剖析.docx》由会员分享,可在线阅读,更多相关《设计一个虚拟存储区和内存工作区编程序演示下述算法的具体实现过程并计算访问命中率剖析.docx(27页珍藏版)》请在冰豆网上搜索。
设计一个虚拟存储区和内存工作区编程序演示下述算法的具体实现过程并计算访问命中率剖析
齐齐哈尔大学
操作系统课程综合实践
题目:
主界面以灵活选择某算法
班级:
计本093
姓名:
赵明秋
学号:
2009021114
指导教师:
韩金库
2008年12月
主界面以灵活选择某算法实验
摘要:
计算机应用专业的学生全面了解和掌握系统软件,一般软件设计方法和技术的必不可少的综合课程,也是了解计算机硬件和软件如何衔接的必经之路。
我觉得此次实验最大的亮点以及不同于别人的地方就是将三种页面置换算法按照课本上老师讲的方式直观简便的输出,在采用输出算法时,我摒弃了常人所用的一维数组输出法,而别出心裁的采用了二维数组的输出算法,模拟了内存的物理块,清晰直观的表达了页面是如何在外存中被调入内存中的,以及各页面在调入过程中是否命中或在置换时又置换了内存中哪个页面。
在软件工程的角度来看,我的系统具有高内聚低耦合的优点,即各种算法之间,并不影响彼此的函数调用,而在各算法的内部,内聚度很高。
关键词:
设计原理,设计方案,流程图,源代码,测试结果,结束语,参考文献
课题运行环境
操作系统:
WindowsXP
编程环境:
MicrosoftVisualC++6.0
1.1实验内容:
通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
熟悉虚拟存储管理的各种液面置换算法,并辨析恶魔你程序实现请求页式存储管理的页面置换算法。
设计一个虚拟存储区和内存工作区,编程序演示下述算法的具体实现过程,并计算访问命中率。
设计要求:
主界面以灵活选择某算法,且以下算法都要实现
1、先进先出算法(FIFO)
2、最近最久未使用算法(LRU)
3、最佳置换算法(OPT)
2.1运行环境
1)操作系统:
WindowsXP
2)编程环境:
MicrosoftVisualC++6.0
3.1设计原理:
3.1.1先进先出算法(FIFO)
最简单的页面置换算法是先入先出(FIFO)法。
这种算法的实质是,总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。
理由是:
最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。
建立一个FIFO队列,收容所有在内存中的页。
被置换页面总是在队列头上进行。
当一个页面被放入内存时,就把它插在队尾上。
这种算法只是在按线性顺序访问地址空间时才是理想的,否则效率不高。
因为那些常被访问的页,往往在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。
FIFO的另一个缺点是,它有一种异常现象,即在增加存储块的情况下,反而使缺页中断率增加了。
当然,导致这种异常现象的页面走向实际上是很少见的。
该算法将所有使用的内存页面构成一个循环列队,每次置换时将队列中的队首唤出,队首指针后移一位即可,算法容易实现牡丹石最先进入内存的野末必将来就不用再到,甚至可能很快就会用到,所以不能保证有效的缺页率,算法性能较差。
3.2.2最近最久未使用算法(LRU)
FIFO算法和OPT算法之间的主要差别是,FIFO算法利用页面进入内存后的时间长短作为置换依据,而OPT算法的依据是将来使用页面的时间。
如果以最近的过去作为不久将来的近似,那么就可以把过去最长一段时间里不曾被使用的页面置换掉。
它的实质是,当需要置换一页时,选择在最近一段时间里最久没有使用过的页面予以置换。
这种算法就称为最久未使用算法(LeastRecentlyUsed,LRU)。
LRU算法是与每个页面最后使用的时间有关的。
当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。
LRU算法是经常采用的页面置换算法,并被认为是相当好的,但是存在如何实现它的问题。
LRU算法需要实际硬件的支持。
其问题是怎么确定最后使用时间的顺序,对此有两种可行的办法:
(1)计数器。
最简单的情况是使每个页表项对应一个使用时间字段,并给CPU增加一个逻辑时钟或计数器。
每次存储访问,该时钟都加1。
每当访问一个页面时,时钟寄存器的内容就被复制到相应页表项的使用时间字段中。
这样我们就可以始终保留着每个页面最后访问的“时间”。
在置换页面时,选择该时间值最小的页面。
这样做,不仅要查页表,而且当页表改变时(因CPU调度)要维护这个页表中的时间,还要考虑到时钟值溢出的问题。
(2)栈。
用一个栈保留页号。
每当访问一个页面时,就把它从栈中取出放在栈顶上。
这样一来,栈顶总是放有目前使用最多的页,而栈底放着目前最少使用的页。
由于要从栈的中间移走一项,所以要用具有头尾指针的双向链连起来。
在最坏的情况下,移走一页并把它放在栈顶上需要改动6个指针。
每次修改都要有开销,但需要置换哪个页面却可直接得到,用不着查找,因为尾指针指向栈底,其中有被置换页。
因实现LRU算法必须有大量硬件支持,还需要一定的软件开销。
所以实际实现的都是一种简单有效的LRU近似算法。
一种LRU近似算法是最近未使用算法(NotRecentlyUsed,NUR)。
它在存储分块表的每一表项中增加一个引用位,操作系统定期地将它们置为0。
当某一页被访问时,由硬件将该位置1。
过一段时间后,通过检查这些位可以确定哪些页使用过,哪些页自上次置0后还未使用过。
就可把该位是0的页淘汰出去,因为在最近一段时间里它未被访问过。
3.3.3最佳置换算法(OPT)
最优置换(OptimalReplacement)是在理论上提出的一种算法。
其实质是:
当调入新的一页而必须预先置换某个老页时,所选择的老页应是将来不再被使用,或者是在最远的将来才被访问。
采用这种页面置换算法,保证有最少的缺页率。
但是最优页面置换算法的实现是困难的,因为它需要人们预先就知道一个进程整个运行过程中页面走向的全部情况。
不过,这个算法可用来衡量(如通过模拟实验分析或理论分析)其他算法的优劣。
该算法能保证有最低的缺页率,所以称为最佳置换算法,但是该算法紧紧是一种理想状况下的算法,因为在进程实际运行过程中,将来会执行到那儿页是不可预知的,所以无法选择该置换那个页出去。
因此,本算法在实际中无法使用,只能作为一种标准来衡量其他算法的性能
4.1设计方案
1)主界面:
设置页面产生算法选择界面和页面置换算法选择界面;
2)子界面:
页面产生算法分为两个界面,分别是随机产生算法和自己输入产生算法。
页面置换算法分为三个子界面,分别是先进先出算法界面、最近最久未使用算法界面、最佳置换算法界面。
5.1流程图
5.1.1主流程图
图
(1)
5.1.2FIFO函数流程图:
图
(2)
5.1.3LRU函数流程图:
图(4)
5.1.4OPT函数流程图:
图(5)
6.源代码
6.1程序代码
#include
#include
#include
#defineBsize3
#definePsize12
#include
usingnamespacestd;
intQString[Psize];
intNum=0;
structpageInfor
{
intcontent;
inttimer;
};
classYZ_replace
{
public:
YZ_replace();
~YZ_replace();
intfindSpace();
intfindExist(intcurpage);
intfindReplace();
voidFIFO();
voidOPT();
voidBlockClear();
voidinitia1(intstring[]);
pageInfor*block;
pageInfor*page;
intmemory_state[Bsize][Psize];
ints;
private:
};
voidP_String(intQString[])
{
inti;
srand((unsigned)time(NULL));
for(i=0;i{
QString[i]=rand()*9/RAND_MAX+1;
}
cout<<"页面走向:
";
for(i=0;i{
cout<}
cout<}
YZ_replace:
:
YZ_replace()
{
s=0;
block=newpageInfor[Bsize];
for(inti=0;i{
block[i].content=-1;
block[i].timer=0;
}
}
voidYZ_replace:
:
initia1(intQString[])
{
intj;
page=newpageInfor[Psize];
for(inti=0;i{
page[i].content=QString[i];
page[i].timer=0;
}
for(i=0;ifor(j=0;jmemory_state[j][i]=0;
}
YZ_replace:
:
~YZ_replace()
{
s=0;
}
intYZ_replace:
:
findSpace()
{
for(inti=0;iif(block[i].content==-1)
returni;
return-1;
}
intYZ_replace:
:
findExist(intcurpage)
{
for(inti=0;iif(block[i].content==page[curpage].content)
returni;
return-1;
}
intYZ_replace:
:
findReplace()
{
intpos=0;
for(inti=0;iif(block[i].timer>=block[pos].timer)
pos=i;
returnpos;
}
voidYZ_replace:
:
FIFO()
{
intexist,space,position;
for(inti=0;i{
exist=findExist(i);
if(exist!
=-1)
{
for(intb=0;b{
memory_state[b][i]=memory_state[b][i-1];
}
s++;
}
else
{
space=findSpace();
if(space!
=-1)
{
for(intb=0;b{
memory_state[b][i]=memory_state[b][i-1];
}
block[space]=page[i];
memory_state[space][i]=block[space].content;
}
else
{
for(intb=0;b{
memory_state[b][i]=memory_state[b][i-1];
}
position=findReplace();
block[position]=page[i];
memory_state[position][i]=block[position].content;
}
}
for(intj=0;jblock[j].timer++;
}
}
voidYZ_replace:
:
BlockClear()
{
for(inti=0;i{
block[i].content=-1;
block[i].timer=0;
}
}
typedefstructpage
{
intnum;
inttime;
}Page;
Pageb[Bsize];
Pagecall[Bsize];
intc[Bsize][Psize];
intqueue[100];
intK;
voidInitL(Page*b,intc[Bsize][Psize])
{
inti,j;
for(i=0;i{
b[i].num=-1;
b[i].time=Psize-i-1;
}
for(i=0;ifor(j=0;jc[i][j]=-1;
}
intGetMax(Page*b)
{
inti;
intmax=-1;
inttag=0;
for(i=0;i{
if(b[i].time>max)
{
max=b[i].time;
tag=i;
}
}
returntag;
}
intEquation(intfold,Page*b)
{
inti;
for(i=0;i{
if(fold==b[i].num)
returni;
}
return-1;
}
voidLru(intfold,Page*b)
{
inti;
intval;
val=Equation(fold,b);
if(val>=0)
{
b[val].time=0;
for(i=0;iif(i!
=val)
b[i].time++;
}
else
{
queue[++K]=fold;
val=GetMax(b);
b[val].num=fold;
b[val].time=0;
for(i=0;iif(i!
=val)
b[i].time++;
}
}
voidYZ_replace:
:
OPT()
{
intexist,space,position;
for(inti=0;i{
exist=findExist(i);
if(exist!
=-1)
{
for(intb=0;b{
memory_state[b][i]=memory_state[b][i-1];
}
s++;
}
else
{
space=findSpace();
if(space!
=-1)
{
for(intb=0;b{
memory_state[b][i]=memory_state[b][i-1];
}
block[space]=page[i];
memory_state[space][i]=block[space].content;
}
else
{
for(intk=0;k{
memory_state[k][i]=memory_state[k][i-1];
for(intj=i;j{
if(block[k].content!
=page[j].content)
{block[k].timer=1000;}
else
{block[k].timer=j;break;}
}
}
position=findReplace();
block[position]=page[i];
memory_state[position][i]=block[position].content;
}
}
}
}
intdecide(stringstr)
{
for(inti=0;i{
if(str[i]<'0'||str[i]>'9')
{
return0;
break;
}
}
returni;
}
inttrans(stringstr)
{
intsum=0;
for(inti=0;isum=sum+(str[i]-'0')*pow(10,str.size()-i-1);
returnsum;
}
intput()
{
inta,d;
stringstr;
cin>>str;
a=decide(str);
while(a==0)
{
cout<<"输入错误,请重新输入!
"<cin>>str;
a=decide(str);
}
d=trans(str);
returnd;
}
voidPut()
{
cout<<"请选择产生页面的方法a:
随机产生b:
输入产生"<cout<<"您选择的菜单是:
";
charF;
cin>>F;
while(F!
='a'&&F!
='b')
{
cout<<"输入错误,请重新输入:
";
cin>>F;
}
if(F=='a')
P_String(QString);
if(F=='b')
{
cout<<"请输入各页面号:
"<for(inti=0;i{
QString[i]=put();
}
}
cout<cout<<"|---------------------------------------------------------------|"<}
voidmain()
{
cout<<"|-----------------------页面置换算法-----------------------|"<cout<<"|---------------------------------------------------------------|"<intt=1;
while(t)
{
Put();
YZ_replacetest1;
YZ_replacetest3;
charselect;
do{
cout<<"请选择要应用的算法:
<1>FIFO算法<2>LRU算法<3>OPT算法<0>退出"<intp,q;
cout<<"请您输入菜单号:
";
cin>>select;
while(select!
='0'&&select!
='1'&&select!
='2'&&select!
='3')
{
cout<<"您的输入无效,请重新输入:
"<cin>>select;
}
if(select=='0')
{
cout<<"您选择的是菜单<0>"<cout<<"完成退出."<t=0;
}
if(select=='1')
{
cout<<"您选择的是菜单<1>"<cout<<"FIFO算法状态:
"<test1.initia1(QString);
test1.FIFO();
test1.BlockClear();
cout<<"-------------------------------------------"<for(p=0;p{
for(q=0;qcout<cout<}
cout<<"-------------------------------------------"<cout<<"命中率:
"<test1.~YZ_replace();
cout<}
if(select=='2')
{
inti,j;
K=-1;
InitL(b,c);
for(i=0;i{
Lru(QString[i],b);
c[0][i]=QString[i];
for(j=0;jc[j][i]=b[j].num;
}
cout<<"您选择的是菜单<2>"<cout<<"LRU算法状态:
"<cout<<"------------------------------------------"<for(i=0;i{
for(j=0;j{
if(c[i][j]==-1)
cout<<"0";
else
cout<<""<}
cout<<""<}
cout<<"------------------------------------------"<cout<<"命中率:
"<<(Psize-(K+1))<<"/"<cout<<'\t';
cout<}
if(select=='3')
{
cout<<"您选择的是菜单<3>"<cout<<"OPT算法状态:
"<test3.initia1(QString);
test3.OPT();
test3.BlockClear();
cout<<"-----------------------------------