虚存管理页面置换算法 — FIFO和RUL算法模拟实现

本篇博文为追忆曾经写过的算法系列第一篇(20081021)

温故知新


目的: 为了解决内存容量有限与多作业运行的冲突,运用了虚拟存储技术,能从逻辑上对内存进行扩充,达到扩充内存的效果。分页存储管理是实现虚拟存储的一种方案。通过模拟算法的实验,加深理解,虚拟存储器的基本原理和方法。


要求: 1.请求分页的置换算法(FIFO && RUL算法实现);2.按给定的顺序列,输出页面调度过程包括命中 / 缺页,调入/调出;3.计算缺页率,频率。


说明

vp_list[N]        //访问序列
bs[M]             //内存块表,M为内存块大小
struct pt{
	int pno;       //页号
	int bno;       //块号
	int flag;       //状态位,为0时在不内存,为1时在内存
    int order;      //优先序号
};


算法流程:

程序:

/* gujinjin 08/10/20 */
/* 程序名称:fifo &&LRU */
/* 程序目的:页面置换算法的FIFO编程实现 */

#include<iostream>
using namespace std;

#define N 20 //访问序列数组大小
#define M 10  //内存块表数组大小

struct pt{
	int pno;	//页号
	int bno;	//块号
	int flag;	//状态位,为0时在不内存,为1时在内存
	int order;	//优先序列
};

/*------------------------------------------*/
/*输入函数*/
/*------------------------------------------*/
void input(int *a,int n)
{
	for(int i=0;i<n;i++){cin>>*a;a++;}
}

/*------------------------------------------*/
/*输出函数*/
/*------------------------------------------*/
void output(int *a,int n)
{
	for(int i=0;i<n;i++){cout<<*a<<'\t';a++;}
	cout<<'\n';
}

/*------------------------------------------*/
/*算法fifo && LRU函数*/
/*------------------------------------------*/
void fifo(int*vp_list,int*bs,int n,int m)
{
	pt ptlist[N];//定义结构数组
	

	int k=0,flag,cn=0,i,j;//cn——统计缺页数
	for(j=0;j<m;j++)//赋初值
	{
		bs[j]=0;
	}

	for(i=0;i<n;i++)// 访问序列循环
	{
		flag=0;
		for(j=0;j<m;j++)
			if(vp_list[i]==bs[j]){flag=1;break;}
		if(flag==1)//命中
		{
			ptlist[i].bno =j+1;
			ptlist[i].flag =1;
			ptlist[i].pno =vp_list[i];
		}
		else{
			ptlist[i].flag =0;
			ptlist[i].pno =vp_list[i];

			bs[k]=vp_list[i];
			ptlist[i].bno =k+1;
			k=(k+1)%m;//取模——循环队列
			cn++;
		}
	}
	cout<<"FIFO算法:\n";
	cout<<"----------------------------------**\n";
	cout<<"缺页率为:"<<'\t'<<(float)cn/n<<'\n';
	cout<<"-------------------------------------------------------------------**\n";
	cout<<"序列号\n";
	cout<<"-------------------------------------------------------------------**\n";
	for(i=0;i<m;i++)
	{
		cout<<vp_list[i]<<"\t缺页!\t"<<"直接存入内存块!\n";
	    cout<<"-------------------------------------------------------------------**\n";
	}
	for(i=m;i<n;i++)
	{
		if(ptlist[i].flag ==0)
			cout<<vp_list[i]<<"\t缺页!\t"<<"调出------块号为"<<ptlist[i].bno <<"--页号为"<<ptlist[i].pno <<'\n';
		else cout<<vp_list[i]<<"\t命中!"<<"\t位置------块号为"<<ptlist[i].bno <<"--页号为"<<ptlist[i].pno <<'\n';;
		cout<<"-------------------------------------------------------------------**\n";
	}
}
void LRU(int*vp_list,int*bs,int n,int m)
{  
	//----------------------------------------------------------------------------------------------**
    pt ptlist_LRU[N];
	int k=0,flag,cn=0,i,j;//cn——统计缺页数
	int com;
	for(j=0;j<m;j++)//赋初值
	{
		bs[j]=0;
	}
	for(j=0;j<n;j++)ptlist_LRU[j].order =0;

	for(i=0;i<n;i++)// 访问序列循环
	{
		flag=0;
		for(j=0;j<m;j++)
			if(vp_list[i]==bs[j]){flag=1;break;}
		if(flag==1)//命中
		{
			ptlist_LRU[i].bno =j+1;
			ptlist_LRU[i].flag =1;
			ptlist_LRU[i].pno =vp_list[i];
			ptlist_LRU[i].order--;
			com=ptlist_LRU[i].order;
			for(j=0;j<m;j++)
				if(ptlist_LRU[j].order <com)
				{com=ptlist_LRU[j].order;k=ptlist_LRU[j].bno ;}
		}

		else{
			ptlist_LRU[i].flag =0;
			ptlist_LRU[i].pno =vp_list[i];

			bs[k]=vp_list[i];
			ptlist_LRU[i].bno =k+1;

			if(i<m)k=(k+1)%m;
			cn++;
		}
	}
	cout<<"LRU*算法:\n";
    cout<<"----------------------------------**\n";
	cout<<"缺页率为:"<<'\t'<<(float)cn/n<<'\n';
	cout<<"-------------------------------------------------------------------**\n";
	cout<<"序列号\n";
	cout<<"-------------------------------------------------------------------**\n";
	for(i=0;i<m;i++)
	{
		cout<<vp_list[i]<<"\t缺页!\t"<<"直接存入内存块!\n";
	    cout<<"-------------------------------------------------------------------**\n";
	}
	for(i=m;i<n;i++)
	{
		if(ptlist_LRU[i].flag ==0)
			cout<<vp_list[i]<<"\t缺页!\t"<<"调出------块号为"<<ptlist_LRU[i].bno <<"--页号为"<<ptlist_LRU[i].pno <<'\n';
		else cout<<vp_list[i]<<"\t命中!"<<"\t位置------块号为"<<ptlist_LRU[i].bno <<"--页号为"<<ptlist_LRU[i].pno <<'\n';;
		cout<<"-------------------------------------------------------------------**\n";
	}
}
	
/*------------------------------------------*/
/*主函数*/
/*------------------------------------------*/
void main()
{
	int vp_list[N],bs[M];//定义访问序列数组和内存块表数组
	int n,m,choose;
	cout<<"输入序列个数:\n";
	cin>>n;
	cout<<"输入内存块大小:\n";
	cin>>m;
	cout<<"请输入访问序列:\n";
	input(vp_list,n);
	cout<<"选FIFO算法输入1,选LRU*算法输入2:";
	cin>>choose;

	cout<<"访问序列:"<<endl;
	output(vp_list,n);
	cout<<"**----------------------------------------**";
	cout<<'\n';
	if(choose==1)
	fifo(vp_list,bs,n,m);//调用fifo函数
	if(choose==2)
	LRU(vp_list,bs,n,m);
}

结果演示:





一、课程设计目的 通过请求页式管理方式中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请 求页式存储管理中的页面置换算法。 容 二、课程设计内容 模拟实现 OPT(最佳置换)、FIFOLRU 算法,并计算缺页率。 示 三、要求及提示 本题目必须单人完成。 1、首先用随机数生成函数产生一个“指令将要访问的地址序列”,然后将地址序列变换 成相应的页地址流(即页访问序列),再计算不同算法下的命中率。 2、通过随机数产生一个地址序列,共产生 400 条。其中 50%的地址访问是顺序执行的, 另外 50%就是非顺序执行。且地址在前半部地址空间和后半部地址空间均匀分布。具体产 生方法如下: 1) 在前半部地址空间,即[0,199]中随机选一数 m,记录到地址流数组中(这是 非顺序执行); 2) 接着“顺序执行一条指令”,即执行地址为 m+1 的指令,把 m+1 记录下来; 3) 在后半部地址空间,[200,399]中随机选一数 m’,作为新指令地址; 4) 顺序执行一条指令,其地址为 m’+1; 5) 重复步骤 1~4,直到产生 400 个指令地址。 3、将指令地址流变换成页地址(页号)流,简化假设为: 1) 页面大小为 1K(这里 K 只是表示一个单位,不必是 1024B); 2) 用户虚存容量为 40K; 3) 用户内存容量为 4 个页框到 40 个页框; 6 4) 用户虚存中,每 K 存放 10 条指令,所以那 400 条指令访问地址所对应的页地 址(页号)流为:指令访问地址为[0,9]的地址为第 0 页;指令访问地址为[10, 19]的地址为第 1 页;……。按这种方式,把 400 条指令组织进“40 页”,并 将“要访问的页号序列”记录到页地址流数组中。 4、循环运行,使用户内存容量从 4 页框到 40 页框。计算每个内存容量下不同页面置换 算法的命中率。输出结果可以为: 页框数 OPT 缺页率 FIFO 缺页率 LRU 缺页率 [4] OPT:0.5566 FIFO:0.4455 LRU:0.5500 [5] OPT:0.6644 FIFO:0.5544 LRU:0.5588 …… …… …… …… [39] OPT:0.9000 FIFO:0.9000 LRU:0.9000 [40] OPT:1.0000 FIFO:1.0000 LRU:1.0000 注 1:在某一次实验中,可能 FIFOLRU 性能更好,但足够多次的实验表明 LRU 的平均性能比 FIFO 更好。 注 2:计算缺页率时,以页框填满之前和之后的总缺页次数计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值