页面置换算法课程设计.docx
《页面置换算法课程设计.docx》由会员分享,可在线阅读,更多相关《页面置换算法课程设计.docx(24页珍藏版)》请在冰豆网上搜索。
![页面置换算法课程设计.docx](https://file1.bdocx.com/fileroot1/2023-2/8/48f2e8ce-5df6-4647-bdd2-38ee47a45552/48f2e8ce-5df6-4647-bdd2-38ee47a455521.gif)
页面置换算法课程设计
操作系统课程设计报告
题目页面置换算法
专业计算机科学与技术
1.设计目的2
2.课设要求2
3.系统分析3
4.系统设计3
4.1问题分析3
4.2程序整体框图5
4.3FIFO算法5
4.4LRU算法6
4.5OPT算法7
5.功能与测试8
5.1开始界面8
5.2FIFO算法9
5.3LRU算法10
5.4OPT算法10
6.结论11
7.附录12
1.设计目的
1、存储管理的主要功能之一是合理地分配空间。
请求页式管理是一种常用的虚拟存储管理技术。
本次设计的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。
2、提高自己的程序设计能力、提高算法设计质量与程序设计素质;
2.课设要求
设计一个请求页式存储管理方案。
并编写模拟程序实现之。
要求包含:
1.过随机数产生一个指令序列,共320条指令。
其地址按下述原则生成:
①50%的指令是顺序执行的;
②25%的指令是均匀分布在前地址部分;
③25%的指令是均匀分布在后地址部分;
具体的实施方法是:
在[0,319]的指令地址之间随机选区一起点M;
顺序执行一条指令,即执行地址为M+1的指令;
在前地址[0,M+1]中随机选取一条指令并执行,该指令的地址为M’;
顺序执行一条指令,其地址为M’+1;
在后地址[M’+2,319]中随机选取一条指令并执行;
重复A—E,直到执行320次指令。
2.指令序列变换成页地址流
设:
(1)页面大小为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先进先出的算法
LRU最近最少使用算法
OPT最佳淘汰算法(先淘汰最不常用的页地址)
3.系统分析
在多道程序环境下,要使程序运行,必须先为之创建进程。
而创建进程的第一步是将程序和数据装入内存。
存储器实现的功能主要是内存分配等功能,本模拟系统所要实现的就是将进程的程序和数据装入内存(物理块)。
具体需要实现的功能如下:
1、读入进程大小,进行分页,确定每一页的指令地址范围;
2、读入一个指令,确定其所在页面,读入内存物理块中。
物理块空闲直接读入,物理块已满,指向下步操作。
3、物理块已满,将要淘汰原来首先进入到内存中的页面,即换出;然后将现在的指令地址页面读入物理块中,即换入。
4.系统设计
4.1问题分析
分页存储管理,是将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页,并为各页加以编号。
相应地,也把内存空间分成与页面相同大小的若干个存储块,称为物理块,在为进程分配内存时,以块为单位将进程中的若干个页分别装入到多个可以不相邻接的物理块中
系统为每个进程建立一个页表,页表给出逻辑页号和具体内存块号相应的关系。
一个页表中包含若干个表目,表目的自然序号对应于用户程序中的页号,表目中的块号是该页对应的物理块号。
请求页式存储管理方式是一种实现虚拟存储器的方式,是指在进程开始运行之前,不是装入全部页面,而是装入一个或零个页面,之后根据进程运行的需要,动态装入其它页面。
当内存空间已满,而又需要装入新的页面时,则根据某种算法淘汰某个页面,以便装入新的页面。
请求页式存储管理主要需要解决以下问题:
系统如何获知进程当前所需页面不在主存;当发现缺页时,如何把所缺页面调入主存;当主存中没有空闲的页框时,为了要接受一个新页,需要把老的一页淘汰出去,根据什么策略选择欲淘汰的页面。
4.2程序整体框图
图4-1程序整体框图
由于该算法规模较小,可以将该系统划分为三块,分别是:
FIFO算法模块、LRU算法模块、OPT算法模块。
4.3FIFO算法
基于程序总是按线形顺序来访问物理空间这一假设,总是淘汰最先调入主存的页面,即淘汰在主存中驻留时间最长的页面。
N
Y
Y
N
4.4LRU算法
LRU置换算法,是根据页面调入内存后的使用情况进行决策的。
由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰。
该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的次数count,,当须淘汰一个页面时,选择现有页面中其count值最大的,即最近最久未使用的页面予以淘汰。
Y
4.5OPT算法
当要调入一页而必须淘汰旧页时,应该淘汰以后不再访问的页,或距现在最长时间后要访问的页。
它所产生的缺页数最少。
这只是一种理想的情况。
图4-4OPT算法程序流程图
5.功能与测试
5.1界面
用户进入系统之后,会有一个选择算法的界面,如下图所示:
选择内存容量,然后点击“随机生成页地址流”按钮,生成页地址流与页面走向,如下图所示:
图5-1选择界面
5.2FIFO算法
用户点击“FIFO算法”按钮,如下图所示:
5.3LRU算法
用户点击“LRU算法”按钮,如下图所示:
5.4OPT算法
用户点击“OPT算法”按钮,如下图所示:
6.结论
对于页面算法,我们平时上课时,只是知道了页面置换算法是怎么做的,并没有想如何去实现这些算法。
在真正要做的时候才发现了问题。
在这次课程设计的过程中,由于之前大家对可视化程序设计不怎么熟悉,在写代码的时候有了许多的麻烦。
最后,在小组成员耐心看了一些C#的书,并且多方实践,终于完成了这次课程设计。
通过该设计,我们学会了存储器的管理内容,利用C#语言实现进程装入内存的的过程,同时也对存储器管理的多种装入方式及内存分区有了更深的了解,特别是页面置换算法的应用。
但也应看到对于实际的存储器应用还有很多地方不能实现真实,在今后的学习中应对所学知识做更深入的挖掘,对于各种算法应用更好的利用。
7.附录
程序源代码
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
namespacePageReplace
{
publicpartialclassForm1:
Form
{
publicint[]page=newint[320];
publicstructStruPage
{
publicintpageNum;
publicintflag;
publicintcount;
publicintdistance;
}
publicStruPage[]struPage=newStruPage[32];//外存上的页面
publicForm1()
{
InitializeComponent();
comboBox1.DropDownStyle=ComboBoxStyle.DropDownList;
for(inti=4;i<=32;i++)
{
comboBox1.Items.Add(i);
}
}
privatevoidbtnRand_Click(objectsender,EventArgse)
{
int[]address=newint[320];
this.rtboxAddress.Text="";
this.rtboxPage.Text="";
Randomram=newRandom();
for(inti=0;i<317;)
{//生成页地址流
intm=ram.Next(319);
address[i++]=m+1;
intm_=ram.Next(0,m+1);
address[i++]=m_+1;
address[i++]=ram.Next(m_+2,319);
}
for(intj=0;j<320;j++)
{//将页地址流转换为页面走向并输出
page[j]=address[j]/10;
this.rtboxAddress.Text+=address[j].ToString()+"\t";
this.rtboxPage.Text+=page[j].ToString()+"\t";
}
this.btnFCFS.Visible=true;
this.btnLRU.Visible=true;
this.btnOPT.Visible=true;
}
privatevoidbtnFCFS_Click(objectsender,EventArgse)
{
//this.btnFCFS.BackColor=Color.Yellow;
for(inti=0;i<32;i++)
{//初始化结构体
struPage[i].pageNum=i;
struPage[i].flag=0;
struPage[i].count=0;
struPage[i].distance=320;
}
intpageReplaceNum=0;//替换的页面数
doubleshootRate;//命中率
intmemorySize=Int32.Parse(comboBox1.Text);//内存的容量
StringoutputString="";//每次替换后的内存状态
intpageLoadedNum=0;//已装入内存的页面数
int[]array=newint[memorySize];//暂存已装入内存的页面号
for(inti=0;iarray[i]=-1;
for(intj=0;j<320;j++)
{
if(struPage[page[j]].flag==0)
{
pageReplaceNum++;
if(pageLoadedNum==memorySize)//内存空间已满
{
struPage[array[0]].flag=0;
for(intk=0;karray[k]=array[k+1];
array[pageLoadedNum-1]=page[j];
struPage[page[j]].flag=1;
}
else//内存空间还有空闲
{
struPage[page[j]].flag=1;
array[pageLoadedNum++]=page[j];
}
}
for(inti=0;i{
if(array[i]==-1)
outputString+="\t";
else
outputString+=array[i].ToString()+"\t";
}
outputString+="\n";
}
shootRate=1-pageReplaceNum/320.0;
this.rtboxMemory.Text="";
this.shootRateBox.Text=shootRate.ToString();
this.rtboxMemory.Text=outputString;
}
privatevoidbtnLRU_Click(objectsender,EventArgse)
{
for(inti=0;i<32;i++)
{//初始化结构体
struPage[i].pageNum=i;
struPage[i].flag=0;
struPage[i].count=0;
struPage[i].distance=320;
}
intpageReplaceNum=0;//替换的页面数
doubleshootRate;//命中率
intmemorySize=Int32.Parse(comboBox1.Text);//内存的容量
StringoutputString="";//每次替换后的内存状态
intpageLoadedNum=0;//已装入内存的页面数
int[]array=newint[memorySize];//暂存已装入内存的页面号
for(inti=0;iarray[i]=-1;
for(intj=0;j<320;j++)
{
struPage[page[j]].count=0;
if(struPage[page[j]].flag==0)//页面未曾装入内存
{
pageReplaceNum++;
if(pageLoadedNum==memorySize)//内存空间已满
{
intmax=0;
for(intk=1;k{
if(struPage[array[k]].count>struPage[array[max]].count)
max=k;
}
//进行页面替换
struPage[array[max]].flag=0;
struPage[page[j]].flag=1;
array[max]=page[j];
for(intn=0;nstruPage[array[n]].count++;
}
else//内存还有空闲
{
struPage[page[j]].flag=1;
array[pageLoadedNum++]=page[j];
for(ints=0;sstruPage[array[s]].count++;
}
}
else//页面已转入内存
{
for(intt=0;tstruPage[array[t]].count++;
}
for(inti=0;i{
if(array[i]==-1)
outputString+="\t";
else
outputString+=array[i].ToString()+"\t";
}
outputString+="\n";
}
shootRate=1-pageReplaceNum/320.0;
this.rtboxMemory.Text="";
this.shootRateBox.Text=shootRate.ToString();
this.rtboxMemory.Text=outputString;
}
privatevoidbtnOPT_Click(objectsender,EventArgse)
{
for(inti=0;i<32;i++)
{//初始化结构体
struPage[i].pageNum=i;
struPage[i].flag=0;
struPage[i].count=0;
struPage[i].distance=320;
}
intpageReplaceNum=0;//替换的页面数
doubleshootRate;//命中率
intmemorySize=Int32.Parse(comboBox1.Text);//内存的容量
StringoutputString="";//每次替换后的内存状态
intpageLoadedNum=0;//已装入内存的页面数
int[]array=newint[memorySize];//暂存已装入内存的页面号
for(inti=0;iarray[i]=-1;
for(intj=0;j<320;j++)
{
if(struPage[page[j]].flag==0)//页面未曾装入内存
{
pageReplaceNum++;
if(pageLoadedNum==memorySize)//内存空间已满
{
intmax=0;
for(intk=1;k{
if(struPage[array[k]].distance>struPage[array[max]].distance)
max=k;
}
//进行页面替换
struPage[array[max]].flag=0;
struPage[page[j]].flag=1;
array[max]=page[j];
intn;
for(n=j+1;n<320;n++)
{//求出替换页面的distance
if(page[n]==page[j])
break;
}
struPage[page[j]].distance=n-j;
}
else//内存还有空闲
{
struPage[page[j]].flag=1;
array[pageLoadedNum++]=page[j];
intm;
for(m=j+1;m<320;m++)
{//求出装入页面的distance
if(page[m]==page[j])
break;
}
struPage[page[j]].distance=m-j;
}
}
else//页面已转入内存
{
intt;
for(t=j+1;t<320;t++)
{//求出装入页面的distance
if(page[t]==page[j])
break;
}
struPage[page[j]].distance=t-j;
}
for(inti=0;i{
if(array[i]==-1)
outputString+="\t";
else
outputString+=array[i].ToString()+"\t";
}
outputString+="\n";
}
shootRate=1-pageReplaceNum/320.0;
this.rtboxMemory.Text="";
this.shootRateBox.Text=shootRate.ToString();
this.rtboxMemory.Text=outputString;
}
}
}