实验名称 存储管理 日期 2020年 05 月20 日
一、实验目的:
存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。
二、实验环境:
Windows10+visual C++6.0
三、实验内容:
PART 1 最近最少使用算法
1)使用随机数发生器共产生150个0~119之间的数,表示各条指令的逻辑(虚)地址,形成在[0,119]的指令地址之间共150条指令的地址序列。地址按下述原则生成:
①50%的指令是顺序执行的;
②25%的指令是均匀分布在(跳转到)前地址部分;
③25%的指令是均匀分布在(跳转到)后地址部分;
#具体的实施方法是:
-
-
- 在[0,119]的指令地址之间随机选取一起点M;
- 顺序执行一条指令,即执行地址为M+1的指令;
- 在前地址[0,M+1]中随机选取一条指令(跳转到)并执行,该指令的地址为M’;
- 顺序执行一条指令,其地址为M’+1;
- 在后地址[M’+2,119]中随机选取一条指令(跳转到)并执行;
- 重复A—E,直到执行150次指令。
-
2)指令序列变换成页地址流
设:用户虚存容量为12K,页面大小为1K,每K存放10条指令,共可以存放120条指令。指令在虚存中的存放方式为:
虚存 页号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
虚存 地址 | [0,9] | [10,19] | [20,29] | [30,39] | [40,49] | [50,59] | [60,69] | [70,79] | [80,89] | [90,99] | [100,109] | [110,119] |
指令 | 第0- 第9条 | 第10- 第19条 | 第20- 第29条 | 第30- 第39条 | 第40- 第49条 | 第50- 第59条 | 第60- 第69条 | 第70- 第79条 | 第80- 第89条 | 第90- 第99条 | 第100- 第109条 | 第110- 第119条 |
3) 用户内存物理页为4页,编程验证LRU最近最少使用算法的工作过程,计算并输出算法的命中率。
4) 修改用户内存物理页为8页,记录输出结果,与4页物理页的情况做比较。
5) 修改用户内存物理页为12页,记录输出结果,与4页、8页物理页情况做比较。
PART 2 先进先出(FIFO)算法
实验内容
利用PART 1中的页面结构形式,编程实现先进先出页面置换算法。
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
#include<time.h>
using namespace std;
struct aa{ //代表一个物理页的节点
int page; //物理页存放的虚存页号
aa* next; //指向下一物理页
};
int main()
{
srand((unsigned)time(0)); //以当前时间做随机种子
int i,addr,pageN,ii,m,answer,ffalse,count,temp1;
double sum;
aa *head,*tail,*temp,*table,*first,*ti;
ffalse=0; //页面失效次数(未命中次数)
answer=0;
int pageNums[150]; //存放页地址流
//------------------------------------------------------------------------------------------
//构建4个节点的链表,表示4个物理页
m=4; //4个物理页
table=new(aa); //建立第一个物理页节点
head=table; //链表头指针指向该节点
table->page=-1; //初值-1表示没有放置虚存页
temp=table; //临时指针指向第一个物理页
for(ii=2;ii<=m;ii++) //继续构建m-1个物理页
{ table=new(aa); //新建一个物理页节点
table->page=-1;
temp->next=table; //前一个节点的next指向本节点,形成链表
temp=table; //临时指针指向新建物理页节点
if (ii==m){table->next=NULL; } //最后物理页节点next指针指向空
}
tail=table; //尾指针指向链表尾
//------------------------------------------------------------------------------------------------
// 在下面的while循环中,每次生成地址流的某一个地址,并计算这个地址
// 所在的逻辑页,根据算法淘汰物理页中的旧页,放入这个地址所在新页
// count变量表示生成的地址流4种不同情况,分别用0,1,2,3表示。
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序执行
// 一条指令(M点+1),即获得M+1的指令地址;
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,该指令的
// 地址为M';
// count=2表示,顺序执行一条指令,其地址为M'+1;
// count=3表示,在后地址[M'+2,119]中随机选取一条指令并执行;
//每4次循环,分4步生成4个地址;再一个4次循环,又分4步生成4个
//地址,以此类推。
//-----------------------------------------------------------------------------------------------
count=0;
i=0;
while(i<150) //每次循环,构造地址流的150个地址中的一个地址
{
if (count==0) { addr =(rand()%120+1)%120; pageN = addr /10;}
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序
//执行一条指令(+1),即获得M+1的指令地址;pageNum为地址所在页号。
if (count==1) { addr =rand()%(addr +1); pageN = addr /10;}
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,
//该指令的地址为M';
if(count==2) { pageN =(( addr +1)%120)/10;}
//顺序执行一条指令,其地址为M'+1;
if(count==3) { pageN =( rand()% (120- (addr+2)) + addr +2)%120/10;}
//在后地址[M'+2,119]中随机选取一条指令并执行; //
++count;
pageNums[i]= pageN ;
if (count==4){count=0;} //进入下一个4次循环,再分4步生成4个地址
i++;
}
//输出页地址流
for(i=0;i<150;i++) { cout<< pageNums[i]<<" ";}
cout<<endl;
//----------------------------------------------------------------------------------------
//以下是FIFO算法
for(i=0;i<150;i++)
{
answer=0; //页命中时(虚页在内存)answer置1
temp=head; //临时指针指向链表头
first=head; // first指针指向链表头
table=head;
while(table!=NULL) //循环查找内存中的虚页号,看是否页命中
{
if (table->page==pageNums[i]){answer=1;temp=table;}
//页命中,answer置1,temp指向命中的物理页节点
table=table->next;
}
if(answer!=1) //如果页没有命中
{
ffalse=ffalse+1; //未命中次数+1
//淘汰第一个物理页中的逻辑页号,其它逻辑页号上移一个位置
temp=head;
while (temp!=NULL&& temp->next!=NULL)
{
temp->page=temp->next->page;
temp=temp->next;
}
tail->page= pageNums[i]; //新的逻辑页(虚页)放入最下面的物理页
}
//---------------------------------------------------------------------------------------
//输出地址变化情况:
for(ti=head;ti!=NULL;ti=ti->next) cout<<ti->page<<" ";
cout<< endl;
}
//-------------------------------------------------------------------------------------
sum=1.0-ffalse/150.0; //计算命中率
cout<<" FIFO算法命中率:"<<sum<<" "<< endl;
}
程序运行截图:
PART 3 实验结果分析
重复运行LRU程序N次,(N值自己设定,如30,50等),记录每次运行得到的命中率,求出N次的命中率平均值。
源代码:
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
#include<time.h>
using namespace std;
#define N 30
struct aa{ //代表一个物理页的节点
int page; //物理页存放的虚存页号
aa* next; //指向下一物理页
};
int main()
{
double avr=0;
for(int j=0;j<N;j++)
{
srand((unsigned)time(0)); //以当前时间做随机种子
int i,addr,pageN,ii,m,answer,ffalse,count,temp1;
double sum;
aa *head,*tail,*temp,*table,*first,*ti;
ffalse=0; //页面失效次数(未命中次数)
answer=0;
int pageNums[150]; //存放页地址流
//------------------------------------------------------------------------------------------
//构建4个节点的链表,表示4个物理页
m=4; //4个物理页
table=new(aa); //建立第一个物理页节点
head=table; //链表头指针指向该节点
table->page=-1; //初值-1表示没有放置虚存页
temp=table; //临时指针指向第一个物理页
for(ii=2;ii<=m;ii++) //继续构建m-1个物理页
{
table=new(aa); //新建一个物理页节点
table->page=-1;
temp->next=table; //前一个节点的next指向本节点,形成链表
temp=table; //临时指针指向新建物理页节点
if (ii==m){table->next=NULL; } //最后物理页节点next指针指向空
}
tail=table; //尾指针指向链表尾
//------------------------------------------------------------------------------------------------
// 在下面的while循环中,每次生成地址流的某一个地址,并计算这个地址
// 所在的逻辑页,根据算法淘汰物理页中的旧页,放入这个地址所在新页
// count变量表示生成的地址流4种不同情况,分别用0,1,2,3表示。
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序执行
// 一条指令(M点+1),即获得M+1的指令地址;
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,该指令的
// 地址为M';
// count=2表示,顺序执行一条指令,其地址为M'+1;
// count=3表示,在后地址[M'+2,119]中随机选取一条指令并执行;
//每4次循环,分4步生成4个地址;再一个4次循环,又分4步生成4个
//地址,以此类推。
//-----------------------------------------------------------------------------------------------
count=0;
i=0;
while(i<150) //每次循环,构造地址流的150个地址中的一个地址
{
if (count==0)
{
addr=(rand()%120+1)%120;
pageN=addr/10;
}
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序
//执行一条指令(+1),即获得M+1的指令地址;pageNum为地址所在页号。
if (count==1)
{
addr=rand()%(addr+1);
pageN=addr/10;
}
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,
//该指令的地址为M';
if(count==2)
{
pageN =((addr+1)%120)/10;
}
//顺序执行一条指令,其地址为M'+1;
if(count==3)
{
pageN =(rand()%(120-(addr+2))+addr+2)%120/10;
}
//在后地址[M'+2,119]中随机选取一条指令并执行; //
++count;
pageNums[i]=pageN ;
if(count==4)
{count=0;} //进入下一个4次循环,再分4步生成4个地址
i++;
}
//输出页地址流
for(i=0;i<150;i++)
{ cout<< pageNums[i]<<" ";}
cout<<endl;
//----------------------------------------------------------------------------------------
//以下是LRU最近最少使用算法
for(i=0;i<150;i++)
{
answer=0; //页命中时(虚页在内存)answer置1
temp=head; //临时指针指向链表头
first=head; // first指针指向链表头
table=head;
while(table!=NULL) //循环查找内存中的虚页号,看是否页命中
{
if (table->page==pageNums[i]){answer=1;temp=table;}
//页命中,answer置1,temp指向命中的物理页节点
table=table->next;
}
if(answer==1) //如果页命中
{
temp1=temp->page; //temp1临时保存物理页中命中的逻辑页号
while (temp!=NULL&& temp->next!=NULL)
//所有比命中页位置低的虚页号上移一个位置
{ temp->page=temp->next->page;
temp=temp->next;
}
tail->page=temp1; //命中的虚页放入最下面的物理页
}
if(answer!=1) //如果页没有命中
{
ffalse=ffalse+1; //未命中次数+1
//淘汰第一个物理页中的逻辑页号,其它逻辑页号上移一个位置
temp=head;
while (temp!=NULL&& temp->next!=NULL)
{
temp->page=temp->next->page;
temp=temp->next;
}
tail->page= pageNums[i]; //新的逻辑页(虚页)放入最下面的物理页
}
//---------------------------------------------------------------------------------------
//输出地址变化情况:
for(ti=head;ti!=NULL;ti=ti->next)
cout<<ti->page<<" ";
cout<< endl;
}
//-------------------------------------------------------------------------------------
sum=1.0-ffalse/150.0; //计算命中率
avr+=sum;
cout<<" LRU算法命中率:"<<sum<<" "<< endl;
}
avr=avr/N;
cout<<" LRU算法的平均命中率:"<<avr<<" "<<endl;
}
程序运行代码:
重复运行FIFO程序N次,(N值自己设定,如30,50等),记录每次运行得到的命中率,求出N次的命中率平均值。
程序代码:
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
#include<time.h>
using namespace std;
#define N 30
struct aa{ //代表一个物理页的节点
int page; //物理页存放的虚存页号
aa* next; //指向下一物理页
};
int main()
{
double avr=0;
for(int j=0;j<N;j++)
{
srand((unsigned)time(0)); //以当前时间做随机种子
int i,addr,pageN,ii,m,answer,ffalse,count,temp1;
double sum;
aa *head,*tail,*temp,*table,*first,*ti;
ffalse=0; //页面失效次数(未命中次数)
answer=0;
int pageNums[150]; //存放页地址流
//------------------------------------------------------------------------------------------
//构建4个节点的链表,表示4个物理页
m=4; //4个物理页
table=new(aa); //建立第一个物理页节点
head=table; //链表头指针指向该节点
table->page=-1; //初值-1表示没有放置虚存页
temp=table; //临时指针指向第一个物理页
for(ii=2;ii<=m;ii++) //继续构建m-1个物理页
{ table=new(aa); //新建一个物理页节点
table->page=-1;
temp->next=table; //前一个节点的next指向本节点,形成链表
temp=table; //临时指针指向新建物理页节点
if (ii==m){table->next=NULL; } //最后物理页节点next指针指向空
}
tail=table; //尾指针指向链表尾
//------------------------------------------------------------------------------------------------
// 在下面的while循环中,每次生成地址流的某一个地址,并计算这个地址
// 所在的逻辑页,根据算法淘汰物理页中的旧页,放入这个地址所在新页
// count变量表示生成的地址流4种不同情况,分别用0,1,2,3表示。
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序执行
// 一条指令(M点+1),即获得M+1的指令地址;
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,该指令的
// 地址为M';
// count=2表示,顺序执行一条指令,其地址为M'+1;
// count=3表示,在后地址[M'+2,119]中随机选取一条指令并执行;
//每4次循环,分4步生成4个地址;再一个4次循环,又分4步生成4个
//地址,以此类推。
//-----------------------------------------------------------------------------------------------
count=0;
i=0;
while(i<150) //每次循环,构造地址流的150个地址中的一个地址
{
if (count==0) { addr =(rand()%120+1)%120; pageN = addr /10;}
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序
//执行一条指令(+1),即获得M+1的指令地址;pageNum为地址所在页号。
if (count==1) { addr =rand()%(addr +1); pageN = addr /10;}
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,
//该指令的地址为M';
if(count==2) { pageN =(( addr +1)%120)/10;}
//顺序执行一条指令,其地址为M'+1;
if(count==3) { pageN =( rand()% (120- (addr+2)) + addr +2)%120/10;}
//在后地址[M'+2,119]中随机选取一条指令并执行; //
++count;
pageNums[i]= pageN ;
if (count==4){count=0;} //进入下一个4次循环,再分4步生成4个地址
i++;
}
//输出页地址流
for(i=0;i<150;i++) { cout<< pageNums[i]<<" ";}
cout<<endl;
//----------------------------------------------------------------------------------------
//以下是FIFO算法
for(i=0;i<150;i++)
{
answer=0; //页命中时(虚页在内存)answer置1
temp=head; //临时指针指向链表头
first=head; // first指针指向链表头
table=head;
while(table!=NULL) //循环查找内存中的虚页号,看是否页命中
{
if (table->page==pageNums[i]){answer=1;temp=table;}
//页命中,answer置1,temp指向命中的物理页节点
table=table->next;
}
if(answer!=1) //如果页没有命中
{
ffalse=ffalse+1; //未命中次数+1
//淘汰第一个物理页中的逻辑页号,其它逻辑页号上移一个位置
temp=head;
while (temp!=NULL&& temp->next!=NULL)
{
temp->page=temp->next->page;
temp=temp->next;
}
tail->page= pageNums[i]; //新的逻辑页(虚页)放入最下面的物理页
}
//---------------------------------------------------------------------------------------
//输出地址变化情况:
for(ti=head;ti!=NULL;ti=ti->next) cout<<ti->page<<" ";
cout<< endl;
}
//-------------------------------------------------------------------------------------
sum=1.0-ffalse/150.0; //计算命中率
avr+=sum;
cout<<" FIFO算法命中率:"<<sum<<" "<< endl;
}
avr=avr/N;
cout<<" FIFO平均算法命中率:"<<avr<<" "<< endl;
}
程序运行截图:
扩大逻辑地址范围,比如调整为[0,319],或者其它的范围,同时增加页地址流长度。对比两种页面置换算法程序运行结果。
LRU:
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
#include<time.h>
using namespace std;
#define N 30
struct aa{ //代表一个物理页的节点
int page; //物理页存放的虚存页号
aa* next; //指向下一物理页
};
int main()
{
double avr=0;
for(int j=0;j<N;j++)
{
srand((unsigned)time(0)); //以当前时间做随机种子
int i,addr,pageN,ii,m,answer,ffalse,count,temp1;
double sum;
aa *head,*tail,*temp,*table,*first,*ti;
ffalse=0; //页面失效次数(未命中次数)
answer=0;
int pageNums[200]; //存放页地址流
//------------------------------------------------------------------------------------------
//构建4个节点的链表,表示4个物理页
m=4; //4个物理页
table=new(aa); //建立第一个物理页节点
head=table; //链表头指针指向该节点
table->page=-1; //初值-1表示没有放置虚存页
temp=table; //临时指针指向第一个物理页
for(ii=2;ii<=m;ii++) //继续构建m-1个物理页
{
table=new(aa); //新建一个物理页节点
table->page=-1;
temp->next=table; //前一个节点的next指向本节点,形成链表
temp=table; //临时指针指向新建物理页节点
if (ii==m){table->next=NULL; } //最后物理页节点next指针指向空
}
tail=table; //尾指针指向链表尾
//------------------------------------------------------------------------------------------------
// 在下面的while循环中,每次生成地址流的某一个地址,并计算这个地址
// 所在的逻辑页,根据算法淘汰物理页中的旧页,放入这个地址所在新页
// count变量表示生成的地址流4种不同情况,分别用0,1,2,3表示。
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序执行
// 一条指令(M点+1),即获得M+1的指令地址;
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,该指令的
// 地址为M';
// count=2表示,顺序执行一条指令,其地址为M'+1;
// count=3表示,在后地址[M'+2,119]中随机选取一条指令并执行;
//每4次循环,分4步生成4个地址;再一个4次循环,又分4步生成4个
//地址,以此类推。
//-----------------------------------------------------------------------------------------------
count=0;
i=0;
while(i<200) //每次循环,构造地址流的150个地址中的一个地址
{
if (count==0)
{
addr=(rand()%320+1)%320;
pageN=addr/10;
}
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序
//执行一条指令(+1),即获得M+1的指令地址;pageNum为地址所在页号。
if (count==1)
{
addr=rand()%(addr+1);
pageN=addr/10;
}
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,
//该指令的地址为M';
if(count==2)
{
pageN =((addr+1)%320)/10;
}
//顺序执行一条指令,其地址为M'+1;
if(count==3)
{
pageN =(rand()%(320-(addr+2))+addr+2)%320/10;
}
//在后地址[M'+2,119]中随机选取一条指令并执行; //
++count;
pageNums[i]=pageN ;
if(count==4)
{count=0;} //进入下一个4次循环,再分4步生成4个地址
i++;
}
//输出页地址流
for(i=0;i<200;i++)
{ cout<< pageNums[i]<<" ";}
cout<<endl;
//----------------------------------------------------------------------------------------
//以下是LRU最近最少使用算法
for(i=0;i<200;i++)
{
answer=0; //页命中时(虚页在内存)answer置1
temp=head; //临时指针指向链表头
first=head; // first指针指向链表头
table=head;
while(table!=NULL) //循环查找内存中的虚页号,看是否页命中
{
if (table->page==pageNums[i]){answer=1;temp=table;}
//页命中,answer置1,temp指向命中的物理页节点
table=table->next;
}
if(answer==1) //如果页命中
{
temp1=temp->page; //temp1临时保存物理页中命中的逻辑页号
while (temp!=NULL&& temp->next!=NULL)
//所有比命中页位置低的虚页号上移一个位置
{ temp->page=temp->next->page;
temp=temp->next;
}
tail->page=temp1; //命中的虚页放入最下面的物理页
}
if(answer!=1) //如果页没有命中
{
ffalse=ffalse+1; //未命中次数+1
//淘汰第一个物理页中的逻辑页号,其它逻辑页号上移一个位置
temp=head;
while (temp!=NULL&& temp->next!=NULL)
{
temp->page=temp->next->page;
temp=temp->next;
}
tail->page= pageNums[i]; //新的逻辑页(虚页)放入最下面的物理页
}
//---------------------------------------------------------------------------------------
//输出地址变化情况:
for(ti=head;ti!=NULL;ti=ti->next)
cout<<ti->page<<" ";
cout<< endl;
}
//-------------------------------------------------------------------------------------
sum=1.0-ffalse/200.0; //计算命中率
avr+=sum;
cout<<" LRU算法命中率:"<<sum<<" "<< endl;
}
avr=avr/N;
cout<<" LRU算法的平均命中率:"<<avr<<" "<<endl;
}
截图:
FIFO:
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
#include<time.h>
using namespace std;
#define N 30
struct aa{ //代表一个物理页的节点
int page; //物理页存放的虚存页号
aa* next; //指向下一物理页
};
int main()
{
double avr=0;
for(int j=0;j<N;j++)
{
srand((unsigned)time(0)); //以当前时间做随机种子
int i,addr,pageN,ii,m,answer,ffalse,count,temp1;
double sum;
aa *head,*tail,*temp,*table,*first,*ti;
ffalse=0; //页面失效次数(未命中次数)
answer=0;
int pageNums[200]; //存放页地址流
//------------------------------------------------------------------------------------------
//构建4个节点的链表,表示4个物理页
m=4; //4个物理页
table=new(aa); //建立第一个物理页节点
head=table; //链表头指针指向该节点
table->page=-1; //初值-1表示没有放置虚存页
temp=table; //临时指针指向第一个物理页
for(ii=2;ii<=m;ii++) //继续构建m-1个物理页
{ table=new(aa); //新建一个物理页节点
table->page=-1;
temp->next=table; //前一个节点的next指向本节点,形成链表
temp=table; //临时指针指向新建物理页节点
if (ii==m){table->next=NULL; } //最后物理页节点next指针指向空
}
tail=table; //尾指针指向链表尾
//------------------------------------------------------------------------------------------------
// 在下面的while循环中,每次生成地址流的某一个地址,并计算这个地址
// 所在的逻辑页,根据算法淘汰物理页中的旧页,放入这个地址所在新页
// count变量表示生成的地址流4种不同情况,分别用0,1,2,3表示。
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序执行
// 一条指令(M点+1),即获得M+1的指令地址;
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,该指令的
// 地址为M';
// count=2表示,顺序执行一条指令,其地址为M'+1;
// count=3表示,在后地址[M'+2,119]中随机选取一条指令并执行;
//每4次循环,分4步生成4个地址;再一个4次循环,又分4步生成4个
//地址,以此类推。
//-----------------------------------------------------------------------------------------------
count=0;
i=0;
while(i<200) //每次循环,构造地址流的150个地址中的一个地址
{
if (count==0) { addr =(rand()%320+1)%320; pageN = addr /10;}
// count=0表示,在[0,119]的指令地址之间随机选取一起点M,顺序
//执行一条指令(+1),即获得M+1的指令地址;pageNum为地址所在页号。
if (count==1) { addr =rand()%(addr +1); pageN = addr /10;}
// count=1表示,在前地址[0,M+1]中随机选取一条指令并执行,
//该指令的地址为M';
if(count==2) { pageN =(( addr +1)%320)/10;}
//顺序执行一条指令,其地址为M'+1;
if(count==3) { pageN =( rand()% (320- (addr+2)) + addr +2)%320/10;}
//在后地址[M'+2,119]中随机选取一条指令并执行; //
++count;
pageNums[i]= pageN ;
if (count==4){count=0;} //进入下一个4次循环,再分4步生成4个地址
i++;
}
//输出页地址流
for(i=0;i<200;i++) { cout<< pageNums[i]<<" ";}
cout<<endl;
//----------------------------------------------------------------------------------------
//以下是FIFO算法
for(i=0;i<200;i++)
{
answer=0; //页命中时(虚页在内存)answer置1
temp=head; //临时指针指向链表头
first=head; // first指针指向链表头
table=head;
while(table!=NULL) //循环查找内存中的虚页号,看是否页命中
{
if (table->page==pageNums[i]){answer=1;temp=table;}
//页命中,answer置1,temp指向命中的物理页节点
table=table->next;
}
if(answer!=1) //如果页没有命中
{
ffalse=ffalse+1; //未命中次数+1
//淘汰第一个物理页中的逻辑页号,其它逻辑页号上移一个位置
temp=head;
while (temp!=NULL&& temp->next!=NULL)
{
temp->page=temp->next->page;
temp=temp->next;
}
tail->page= pageNums[i]; //新的逻辑页(虚页)放入最下面的物理页
}
//---------------------------------------------------------------------------------------
//输出地址变化情况:
for(ti=head;ti!=NULL;ti=ti->next) cout<<ti->page<<" ";
cout<< endl;
}
//-------------------------------------------------------------------------------------
sum=1.0-ffalse/200.0; //计算命中率
avr+=sum;
cout<<" FIFO算法命中率:"<<sum<<" "<< endl;
}
avr=avr/N;
cout<<" FIFO平均算法命中率:"<<avr<<" "<< endl;
}
四、心得体会:
通过比较LRU最近最久未使用算法与FIFO算法,了解了这两种算法的优缺点,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。