请求页式管理缺页中断模拟设计--FIFO、OPT

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

课程设计
题目请求页式管理缺页中断模拟设计
--FIFO、OPT
学院计算机科学与技术
专业
班级
姓名
指导教师吴利军
2013 年 1 月16 日
课程设计任务书
学生姓名:
指导教师:吴利军_ 工作单位:计算机科学与技术学院题目: 请求页式管理缺页中断模拟设计--FIFO、OPT
初始条件:
1.预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会和了解缺页和页面置换的具体实施方法。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
1.实现指定淘汰算法。

能够处理以下的情形:
⑴能够输入给作业分配的内存块数;
⑵能够输入给定的页面,并计算发生缺页的次数以及缺页率;
⑶缺页时,如果发生页面置换,输出淘汰的页号。

2.设计报告内容应说明:
⑴需求分析;
⑵功能设计(数据结构及模块说明);
⑶开发平台及源程序的主要部分;
⑷测试用例,运行结果与运行情况分析;
⑸自我评价与总结:
i)你认为你完成的设计哪些地方做得比较好或比较出色;
ii)什么地方做得不太好,以后如何改正;
iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);
iv)完成本题是否有其他方法(如果有,简要说明该方法);
时间安排:
设计安排一周:周1、周2:完成程序分析及设计。

周2、周3:完成程序调试及测试。

周4、周5:验收、撰写课程设计报告。

(注意事项:严禁抄袭,一旦发现,一律按0分记)
指导教师签名:年月日
系主任(或责任教师)签名:年月日
请求页式管理缺页中断模拟设计
——FIFO、OPT
1课程设计目的与功能
1.1设计目的
结合《操作系统》所学内存页式管理章节,掌握虚拟内存设计的重要性,熟悉和掌握请求分页式存储管理的实现原理,通过分析、设计和实现页式虚拟存储管理缺页中断的模拟系统,重点掌握当请求页面不在内存而内存块已经全部被占用时的替换算法(主要通过FIFO和OPT实现),并考察替换算法的评价指标——缺页次数和缺页率,得到淘汰的页面次序。

高级语言设计并实现出的结果程序要能够很好地显示页面调入和替换详细信息。

1.2初始条件及可发环境
1.2.1初始条件
1.预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会和了解缺页和页面置换的具体实施方法。

2.实践准备:掌握一种计算机高级语言的使用。

1.2.2开发环境
(1)使用系统:Windows XP
(2)使用语言:C++
(3)开发工具:Visual C++ 6.0
1.3功能实现
设计的结果程序能实现FIFO、OPT算法模拟页式存储管理缺页中断,主要能够处理以下的情形:
(1) 用户能够输入给定分配的内存块数;
(2) 用户输入给定的页面,并计算发生缺页的次数、缺页率及淘汰页面次序;
(3) 程序可随机生成页面序列,或用户输入;
2需求分析及设计说明
2.1需求分析
由于纯页式存储管理提高了内存的利用效率,但并不为用户提供虚存,并且会产生磁盘碎片问题。

用户程序将受到物理内存大小的限制。

而虚存的存储管理技术
——请求分页存储管理技术和请求分段技术,则很好的解决了这个问题。

该设计虚拟实现请求分页管理(只实现FIFO和OPT)。

请求分页系统是在分页系统的基础上,增加了请求调页功能和页面置换功能所形成的页式虚拟存储系统。

它允许只装入部分页面的程序和数据,便启动运行。

以后,再通过调页功能和页面置换功能,陆续把即将要运行的页面调入内存,同时把暂时不运行的页面换出到外存上,置换时以页面为单位。

实现将程序正在运行时所需的但尚未在内存的页面调入内存,再将内存中暂时不用的页面从内存置换到外存磁盘上。

为了实现请求分页技术,页表应增加相应的内容,反映该页是否在内存,在外
存的位置,和在内存的时间的长短。

请求分页中的页表如表1:
表1
各字段说明如下:
状态位:指示该页是否已调入内存。

访问字段:记录本页在被访问的次数,或记录最近已有多长时间未被访问。

修改位:表示该页面在调入内存后是否被修改过。

若未被修改,在替换该页时就不需要再将该页写回到外存上,以减少系统的开销和启动磁盘的次数;若已被修改,则必须将该页重写到外存上,以保证外存中所保留的始终是最新副本。

外存地址:指出该页在外存上的地址,通常是物理块号。

在本设计中模拟FIFO、OPT系统的实现中,只需要用到虚拟页号,物理块号和中断位。

页表可用一个结构体的数组实现。

请求分页的具体实现过程如图1
图1请求分页流程图
2.2设计说明
2.2.1算法分析
在进程运行过程中,若其所要访问的页面不在内存,需要把它们调入内存,但内存已无空闲已空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据,送磁盘的对换区。

但应将哪个页面调出,必须根据替换算法来确定。

该设计采用的是常见置换算法中的先进先出(FIFO)、理想型淘汰算法OPT(Optimal Replacement Algorithm)。

详细算法原理如下:
FIFO(先进先出算法)基本思想:总是选择在内存驻留时间最长的一页将其淘汰,因为最早调入内存的页,不再被使用的可能性比近期调入内存的大。

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

但是该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如有全局变量、常用函数,例程等的页面,FIFO算法并不能保证这些页面不被淘汰。

使用FIFO替换算法效率比较低,可能会比理想型算法要多出一倍。

低的原因是:基于处理器按线性顺序访问地址空间这一假设。

事实上,许多时候,处理器不是按线性顺序访问地址空间的。

例如,执行循环结构的程序段。

使用FIFO算法时,在未给进程或作业分配足够它所需要的页面数时,有时会出现分配的页面数增,缺页次数反而增加的现象(Belady现象)。

例如针对请求序列:1 2 3 4 1 2 5 1 2 3 4 5,若分配3个可用内存块,使用FIFO算法,一共会缺页9次,缺页率:75%;而如果分配4个可用内存块,则一共会缺页10次,缺页率:83.3%。

OPT(理想型淘汰算法)基本思想:当要调入一新页而必须淘汰一旧页时,所淘汰的页是以后不再使用的,或者是以后相当长的时间内不会使用的。

采用理想型替换算法,通常可保证获得最低的缺页率。

但是由于人们目前无法预知一个进程在内存的若干个页面中,哪个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但是在模拟设计中,由于是事先给定一个页面序列,即知道各个时刻以前和以后的页面出现情况,所以可实现该算法。

在实际系统中,虽无法实现理想型淘汰算法,但是可用它来评价其他替换算法。

2.2.2数据结构
模拟设计时,页表没项记录的数据类型用结构体定义。

整该页表用数组模拟。

结构体有三个成员:int page_num 表示页面号;int memory_num表示页面所对应的内存块号;int is_in_memory是存在状态位标志,表示页面是否在内存,0表示不在内存,1表示在内存。

在每一个算法函数中都要初
始化页表,否则,后面的算法会受前面算法结果的影响。

struct page
{
int page_num; //表示页面号
int memory_num; //表示页面所对应的内存块号
int is_in_memory;//是存在状态位标志,表示页面是否在内存,
0 表示不在内存,1表示在内存
};
page page_table[初始值];
for(int i=0;i<10;i++) //初始化页表:
{
page-table[i].page_num=i;
page_table[i].memory_num=-1; //初始化,内存块号为-1,即没在内存块中。

page_table[i].is_in_memory =0; //初始化时,各页面均不在内存}
页面请求序列:int *page_array= new int[inputSize]。

内存在程序中模拟内存存放页面号:int *memory=new int[memorySize]
2.2.3函数实现
Control()函数是class control的构造函数,用来初始化页表、内存(调用initial()函数)。

提示并接受用户输入等待调入页面数page_size,可用物理块数
memory_size,并随机生成请求页面,或用户自己输入。

然后调用FIFO()、OPT()
函数实现按不同替换算法调入页面进内存。

void FIFO()函数实现先进先出的替换算法调入页面。

void OPT()函数实现理想型替换算法。

3程序的主要模块说明
3.1 control类封装内存管理
3.1.1 FIFO替换算法实现伪函数
void control::FIFO(){
control::init(); 初始化页表等
do{
if(当前页在内存)
else(当前页不在内存,直接加载进入物理块){
缺页累积;
加载当前页进入内存;
修改页表置当前页在页表的是否在内存标志为1。

将该页在内存的位置对应。

}
}while(内存物理块没有加载满);
//内存物理块已经加载满了;
for(剩下的页面循环){
if(当前页在内存)
else(当前页不在内存){
缺页累积。

替换页面;
修改页表置当前页在页表的是否在内存标志为1。

将该页在内存的位置对应。

利用算法得到下次替换的物理块号。

}
}
输出缺页次,缺页率,淘汰页面次序。

}
3.1.2 OPT替换算法实现伪函数
void control::OPT()
{
control::init();//初始化页表等
for(对每个页表循环处理)
{
for(检查每个物理块)
{
if (如果该页在内存物理块中)
置判别标志为1
}
if(如果该页不在内存,并且物理快放满)
{
缺页累加并权值数组每个记录元素清零
for(物理块每个元素检查)
{
for(从该页后面的那个页开始计算权值)
权值累加;
}
得到最大权值所在的物理块,即是下次需要替换的页
替换该页,加入内存
}
if(该页不在内存,并且内存物理块没有满)
{
缺页累加
直接加载进内存
}
}
输出缺页次、缺页率和淘汰页号次序。

}
3.2 main函数
利用页式管理control类建立一个对象,来实现FIFO、OPT。

4使用说明及运行分析
4.1使用说明及运行
运行程序根据提示输入调入页面数和可使用的物理块数,再选择是用户输入还是计算机随机产生页面号。

观察页面调度过程,处理完各页面后,统计并显示缺页次数、缺页率和淘汰页面号次序。

4.2测试实例和运行结果
4.2.1 FIFO算法
输入给定的页面数:10
输入给作业分配内存的物理块数:3
随机生成页面请求序列,如图2:
5 7 3 8 8 0 5 4 5 2
图2
运行结果如图3 图3
4.2.2 OPT算法
输入给定的页面数:10
输入给作业分配内存的物理块数:3
随机生成页面请求序列,如图4:
7 8 2 6 7 8 1 5 6 5
图4
运行结果如图5 图5
4.3结论与分析
从运行结果看出程序能满足模型设计的要求,提示用户对请求序列的大小和可用内存数量进行限制,并提示用户输入请求序列号,或系统随机生成序列,按照不同的替换算法处理并且显示请求页面的调入和替换情况。

通过以上运行,比较各种算法的缺页次数和缺页率,可以看出OPT替换算法具有最小的缺页率。

虽理论上最优,但是实际却无法实现该算法。

5自我评价与总结
在完成了模拟系统的设计和实现后,觉得自己确实获益匪浅。

首先,值得肯定的是:能够一开始就清晰分析了程序的设计流程及实现要求与原理,利用流程图,较好地理解了请求分页的工作流程;俩个主要算法设计较合理,实现容易;结果显示清楚,能较好的反映各请求页面的存在和替换信息。

此外还借助C++语言的类class封装的方法将页式管理整个操作封装起来,容易补充,数据更安全,有益于继承,使功能更强大。

然而,设计不足的地方也是存在的:模拟系统中,用的是一个数组(数据分配连续)来模拟内存空间而实际系统请求分页存储管理时,所分配的内存是不连续的,或许可能用链
表的形式可以改进;另外,在设计OPT算法时,语句嵌套太多,不利于程序的阅读,而且参数和标志的变量的设计不太合理,也加深了程序不利于阅读。

最后,没能实现内存很直观的调度过程的呈现。

其次,在设计过程中,为了较好地完成设计,也参阅和回忆结合了其他相关知识,操作系统相关知识为主要架构,高级语言c++知识为工具。

此过程的学习,丰富和巩固了操作系统的理论知识,对课堂上不明确和不懂的知识,如请求分页的工作流程,都得到了很好补充学习,同时也增加了c++语言本身的应用能力,极大提高了自身学习该门语言的热情。

懂得了编译、调试过程中错误的判断与矫正,积累了不少经验。

最后,个人认为课程设计的范围还可以放的更广些,例如就实现内存页式(或段式)的管理,可以一起包含些内容,如地址的转换,空间的分配与回收,和虚存调度等,这样可以更概括的,更有逻辑,更全面的加深对计算机各个逻辑块的工作原理。

本科生课程设计成绩评定表
班级:物联网1001姓名:张灏学号:0121010340714
及格(60-69分)、60分以下为不及格
指导教师签名:
2013年月日
附录:
F1参考文献
[1]张尧学,史美林编著.计算机操作系统教程(第三版).清华大学出版社.2006 [2]闵联营,何克右主编.C++程序设计教程.武汉理工大学出版社.2005
F2源代码
以下文件在control.h中
#include<iostream>
#include<iomanip>//格式化输出
#include<time.h>//随机数的头文件
using namespace std;
struct page{
int page_num; //////页面号
int memory_num; /////页面对应的内存物理块号
int is_in_memory; /////状态标志,判断页面是否在内存
};
class control{
public:
control();//构造函数
~control();//析构函数
void init();//初始化函数,对页表,物理块进行初始化
void FIFO();
void OPT();
void print();//输出在物理块中当前存在的页号
private:
page page_table[10];//创建页表大小有10项
int page_size,memory_size;//输入的页面数和内存物理块数
int *page_array,*memory;//请求页面的输入序列,和模拟内存用来存放序列号
};
void control::init(){
for(int i=0;i<10;i++){
page_table[i].page_num=i;
page_table[i].memory_num=-1;
page_table[i].is_in_memory=0;
}
for(int i=0;i<memory_size;i++)
memory[i]=-1;
}
control::control(){
int select1 ,select2;////////分别指示是随机产生序列或用户输入和选择哪种替换算法char choice;
cout<<"输入给定的页面数:"<<endl; cin>>page_size;
cout<<"输入给作业分配内存的物理块数"<<endl; cin>>memory_size;
page_array=new int[page_size];memory=new int[memory_size];
loop: cout<<" -------------------------------------"<<endl;
cout<<" 0.用户输入请求序列1.随机生成请求序列"<<endl;
cout<<" -------------------------------------"<<endl;
cin>>select1;
if(select1==1){
cout<<"随机生成页面请求序列(0-10)"<<endl;
int temp1;
for(int i=0;i<page_size;i++){
temp1=rand()%10;
cout<<temp1<<" ";
page_array[i]=temp1;
}
cout<<endl;
}
else if(select1==0){
int temp2;
cout<<"输入"<<page_size<<"个请求页面号(0-10)"<<endl;
for(int i=0;i<page_size;i++){
cin>>temp2;
page_array[i]=temp2;
}
}
else exit(0);
cout<<"请选择使用那种替换算法:0、退出1、FIFO 2、OPT"<<endl;
cin>>select2;
if(select2==1) control::FIFO();
else if(select2==2) control::OPT();
else exit(0);
cout<<"是否继续?(Y/y or N/n)";
cin>>choice;
if(choice=='Y' || choice=='y') goto loop;
else exit(0);
}
control::~control(){
delete []page_array; delete []memory;
}
void control::print(){
for(int q=0;q<memory_size;q++)
cout<<memory[q]<<" ";
}
void control::FIFO(){
cout<<"-----------------FIFO-----------------"<<endl;
control::init();
int *save=new int[page_size];
int count=0;
int times=0;//记录缺页次数
int first_inMemory=0;//记录最先被占用的物理块号,装有最先进入内存的页面号
int is_full=0;//记录物理块是否已被占满,当is_full=memory_size时表示已经装满,如果再缺页则发生替换
int page=0;//记录将要访问的页面号
control::print();
do{//当内存没有放满
if(page_table[page_array[page]].is_in_memory==1){
cout<<setw(8)<<page_array[page]<<" 已经在内存!"<<endl;
page++;
control::print();
if(page==page_size) break;//页面已经全部调用
else continue;
}
else{
times++;
cout<<setw(8)<<page_array[page]<<" 不在内存,直接加载页面!"<<endl;
memory[is_full]=page_array[page];
control::print();
for(int j=0;j<10;j++){
if(page_table[j].memory_num==is_full) {//该物理地址已经被占用
page_table[j].memory_num=-1; page_table[j].is_in_memory=0;
break;
}
}
page_table[page_array[page]].is_in_memory=1;
page_table[page_array[page]].memory_num=is_full;
is_full++; page++;
if(page==page_size) break;
}
}while(is_full!=memory_size);
for(int i=page;i<page_size;i++){//////////当内存已经放满,需要替换
if(page_table[page_array[i]].is_in_memory==1){
cout<<setw(8)<<page_array[i]<<" 已经在内存!"<<endl;
control::print();continue;
}
else{
times++;
memory[first_inMemory]=page_array[i];
for(int j=0;j<10;j++){
if(page_table[j].memory_num==first_inMemory){
cout<<setw(8)<<page_array[i]<<" 不在内存,替换页面:"<<j<<endl;
save[count++]=j;
page_table[j].memory_num=-1; page_table[j].is_in_memory=0;
break;
}
}
control::print();
page_table[page_array[i]].is_in_memory=1;
page_table[page_array[i]].memory_num=first_inMemory;
first_inMemory=(first_inMemory+1)%memory_size;
}
}
cout<<" "<<"页面处理完成"<<endl<<"缺页次数:"<<times<<endl;
cout<<"缺页率:"<<double(times)/page_size*100<<"%"<<endl;
cout<<"淘汰页号的序列为:";
for(int i=0;i<count;i++) cout<<save[i]<<"->";
cout<<"结束"<<endl;
cout<<"--------------------------------------"<<endl;
}
void control::OPT(){
cout<<"-----------------OPT------------------"<<endl;
control::init();
int *change_page=new int[page_size];//存放被淘汰的页面号
int *weight=new int [memory_size];//表示权值
for(int i=0;i<page_size;i++)
change_page[i]=-1;
int lackTime=0 ,k=0,l=0, max=0;
bool in=0;
control::print();
for(int i=0;i<page_size;i++){
in=0;
for(int q=0;q<memory_size;q++){
if (page_array[i]==memory[q]) {//如果该页在内存物理块中
in=1;//置判别标志为1
cout<<setw(8)<<page_array[i]<<"已经在内存!"<<endl;
break;
}
}
if(in==0 && memory[memory_size-1]!=-1) {//如果该页不在内存,并且物理快放满lackTime++;//缺页累加
for(int q=0;q<memory_size;q++)
weight[q]=0;
for(int q=0;q<memory_size;q++){
for(int p=i+1;p<=page_size;p++){
weight[q]++;
if(memory[q]==page_array[p])break;
}
}
max=0;
for(int q=0;q<memory_size;q++){
if(weight[q]>max)
max=weight[q];
}
int q;
for(q=0;q<memory_size;q++)
if (max==weight[q]) break;
change_page[k++]=memory[q];
memory[q]=page_array[i];
cout<<setw(8)<<page_array[i]<<"不在内存,替换页面:"<<memory[q]<<endl;
}
if(in==0 && memory[memory_size-1]==-1) {//该页不在内存,且内存物理块没有满lackTime++;//缺页累加
memory[l++]=page_array[i];
cout<<setw(8)<<page_array[i]<<"不在内存,直接加载页面!"<<endl;
}
control::print();
}
cout<<" "<<"页面处理完成"<<"缺页次数:"<<lackTime<<endl;
cout<<"缺页率:"<<double(lackTime)/page_size*100<<"%"<<endl;
cout<<"淘汰页号:";
for(int m=0;m<k;m++)
cout<<change_page[m]<<"->";
cout<<"结束"<<endl;
cout<<"----------------------------------------"<<endl;
}以下文件在main.cpp中。

#include"control.h"
int main()
{
control c;//建立一个对象
return 0;
}
武汉理工大学《计算机操作系统教程》课程设计报告书
20
20。

相关文档
最新文档