原创 先进先出FIFO页面置换算法

2010-3-30 11:25 16116 7 7 分类: 软件与OS

实验题目:                                      机时: 4<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


<实验二模拟页式虚拟存储管理地址转换和缺页中断


目的与任务


虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量进行扩充的一种存储器系统。在虚拟存储器系统中,作业无需全部装入,只要装入一部分就可运行。本实验使用请求分页存储管理。建立一个页表,要访问页面时,先查页表,若当前页在内存中,直接访问,不在内存中则调入该页到内存中,同时用FIFO算法淘汰最先进入内存的页。


内容和要求


FIFO淘汰算法是最先使用的页面最先被淘汰。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面


先进先出(FIFO)页面置换算法,是根据页面调入内存后的使用情况进行决策的。该算法是选择在内存中驻留时间最久的页面予以淘汰。该算法赋于请求调入页面一个空间(工作集),淘汰掉最先调入的页,取而代之的是紧随它进来的页,这样就基本上实现了对最先进入内存的页面的淘汰。


三 .实验过程   


   我在程序设计过程中,只实现了页面的调入,淘汰等模拟过程,没有涉及到地址变换,所以程序中去掉了关于主存块号,磁盘上的位置等内容,程序相对简单。下面是对程序相关内容说明:


1.定义页数和内存块数


     #define m 5     //m表示页数


#define n 3     //n表示物理块数


2.页表与物理块


由于页表里的内容我只保留了两项,一个时页号,一个是标志,所以我将页表演变位一个一维数组


       int PageTable[m];  


数组PageTable大小为m,分别存储对应页面的状态,表示该页面是否在内存中。状态位 =1表示该页在物理块中,=0表示不在内存中,默认处置为0。如PageTable[0]=1表示页面1在物理块中,PageTable[2]=0表示表示页面3不在物理块中。


  用一个一维数组表示n个物理块中的内容


       int Block[n];


  数组中数值表示对应物理块中装入的页的编号。数组初始值都为0,表示没有装入页。如Block[3]={312},则表示物理块中当前装入页为第123页。


3.访问页面


     访问页面通过一个访问函数实现


         void Visit(int);    //访问函数


 访问过程中会遇到三种情况


  A. 访问页时没有命中,且内存未装满,产生缺页中断,直接调入访问页


     需要进行的操作有:产生缺页中断,中断次数加1,将访问页调入内存,修改


此页的状态,


              interrupt++;       //缺页中断次数加1


        PageTable[x-1]=1;  //修改状态位


         Block=x;     //x调入物理块


   


  B. 访问页时命中


     此时直接访问


             


 C. 访问页时内存已装满,且没有命中,产生缺页中断,调入该页至内存,淘汰最先进入的页


    需要进行的操作有:产生缺页中断,中断次数加1,淘汰最先进入的页(即淘汰页指针所指的页)并修改淘汰页的状态位,调入访问页到物理块并修改调入页的状态位,最后还要修改淘汰页指针指向下一次需要淘汰的页


         interrupt++;       //缺页中断次数加1


           PageTable[Block[k]-1]=0;     //Block[k]被淘汰,状态位修改为 0


    Block[k]=x;         //x调入物理块


           PageTable[x-1]=1; //x状态位修改为 1


           k=(k+1)%n;              //修改下次被淘汰页指针



4.主函数


在主函数中输入页面走向,将其存入进程访问序列process[20]进程访问序列,然后依次访问即可。









四 .实验结果      


    参照课本126页表可以看出结果十分正确。







试验程序:


#include<iostream.h>
#include<iomanip.h>


#define m 5     //m表示页数
#define n 3     //n表示物理块数
float interrupt="0".; //产生缺页中断的次数
int k="0";            //指向最先进入内存的页,即被淘汰的页
int PageTable[m];   //定义页表,总共m页,数组中数值是状态位 =1表示该页在内存中,=0表示不在内存中,默认处置为0
int Block[n];       //定义物理块,总共n个,数组中数值表示对应物理块中装入的页的编号
int process[20];    //进程访问序列
int number="1";       //用于标志访问次数
void Visit(int);    //访问函数


/********************************************************************************
                                 主函数
********************************************************************************/
void main (void)
{
 int input;        
 cout<<"某进程共有"<<m<<"页,请输入进程访问序列(范围:1-"<<m<<",用0表示结束):\n";
 cin>>input;
 for(int length="0";input!=0;length++)   //将输入序列存入process数组,长度为length
 {
  process[length]=input;  
  cin>>input;
 }                         


 for(int j="0";j<length;j++)
  Visit(process[j]);   //依次访问页process[j]
 cout<<"共"<<length<<"次访问,产生"<<interrupt<<"次缺页中断,缺页率为 "<<interrupt/length<<"\n";
}
/********************************************************************************
                                 访问函数
********************************************************************************/
void Visit(int x)
{
 int i,j;
 cout<<setw(2)<<number<<": 访问页"<<x<<"  ";   //第number次访问,访问页x



 for(i=0;i<n;i++) 
 {
     if(Block==0)   //访问页x时没有命中,且内存未装满,产生缺页中断,直接调入访问页
     {
                interrupt++;       //缺页中断次数加1
          PageTable[x-1]=1;  //修改状态位
             Block=x;     //页x调入物理块
          cout<<"缺页中断  内存未满 调入页"<<x<<"  物理块内的页为 ";
          for(j=0;j<=i;j++)cout<<Block[j]<<" ";    //输出物理块内的页号
          cout<<"\n";
    break;
     }
     if(PageTable[x-1]==1)   //访问页x时命中
     {
      cout<<"命中                        物理块内的页为 ";
            for(j=0;j<n && Block[j]!=0;j++)cout<<Block[j]<<" ";      //输出物理块内的页号
      cout<<"\n";
      break;
     }
 }
    if(i==n)   //访问页x时内存已装满,且没有命中,产生缺页中断,调入该页至内存,淘汰最先进入的页
 { 
     cout<<"缺页中断   淘汰页"<<Block[k]<<" 调入页"<<x<<"  物理块内的页为 ";
     interrupt++;       //缺页中断次数加1
           PageTable[Block[k]-1]=0;     //页Block[k]被淘汰,状态位修改为 0
     Block[k]=x;         //页x调入物理块
           PageTable[x-1]=1; //页x状态位修改为 1
           k=(k+1)%n;              //修改下次被淘汰页指针
           for(j=0;j<n;j++)cout<<Block[j]<<" ";      //输出物理块内的页号
     cout<<"\n";
 }


 number++;    //访问次数加1
}

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /3 下一条