【操作系统】页面置换算法模拟实验-C语言版本

1.了解虚拟存储技术的特点;
2.掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程;
3.比较它们的效率

问题的描述
设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。
1、最佳淘汰算法(OPT)
2、先进先出的算法(FIFO)
3、最近最久未使用算法(LRU)
4、最不经常使用算法(LFU)
命中率=1-页面失效次数/页地址流长度

算法的定义
1、最佳淘汰算法(OPT):
从主存中移出永远不再需要的页面;如无这样的页面存在,则选择最长时间不需要访问的页面。于所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。 即被淘汰页面是以后永不使用或最长时间内不再访问的页面。
2、先进先出的算法(FIFO):
当需要淘汰一个页面时,总是选择驻留主存时间最长的页面进行淘汰,即先进入主存的页面先淘汰。其理由是:最早调入主存的页面不再被使用的可能性最大。 即优先淘汰最早进入内存的页面。
3、最近最久未使用算法(LRU):
利用局部性原理,根据一个作业在执行过程中过去的页面访问历史来推测未来的行为。它认为过去一段时间里不曾被访问过的页面,在最近的将来可能也不会再被访问。所以,这种算法的实质是:当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。 即淘汰最近最长时间未访问过的页面。
4、最不经常使用算法(LFU):
选择近期最少访问的页面作为被替换的页面,选择最近时期内使用次数最少的页作为淘汰页。这种算法为每个页保留一个用于记录页被访问次数的计数器,每次选择其访问计数器值最小的页换出。
实验代码

#define Ture 1
#define FALSE 0 
#define INVALID -1
#define NULL 0

#include 
#define	total_instruction	320	/*指令流长*/
#define	total_vp	32		/*虚页长*/
#define	clear_period	50		/*清0周期*/
typedef struct
{
int pn,pfn,counter,time;
}pl_type;

pl_type pl[total_vp];

struct pfc_struct{ 
	int pn,pfn;
	struct pfc_struct *next;
};
typedef struct pfc_struct pfc_type;
pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail; int diseffect,	a[total_instruction];
int page[total_instruction],	offset[total_instruction];

int	initialize(int); int FIFO(int);
int LRU(int); int LFU(int); int OPT(int);

int main( )
{
int s,i,j;
srand(10*getpid());	/*由于每次运行时进程号不同,故可用来作为初始化随机数队列的"种子"*/
s=(float)319*rand( )/32767/32767/2+1;	// for(i=0;i
if(s<0||s>319)
{
printf("When i==%d,Error,s==%d\n",i,s); 
//exit(0);
}
a[i]=s;	/*任选一指令访问点m*/
a[i+1]=a[i]+1;	/*顺序执行一条指令*/ a[i+2]=(float)a[i]*rand( )/32767/32767/2; /*执行前地址指令m' */ a[i+3]=a[i+2]+1;	/*顺序执行一条指令*/

s=(float)(318-a[i+2])*rand( )/32767/32767/2+a[i+2]+2; if((a[i+2]>318)||(s>319))
printf("a[%d+2],a number which is :%d and s==%d\n",i,a[i+2],s);

for(i=0;i<total_instruction;i++)/*将指令序列变换成页地址流*/
{
page[i]=a[i]/10; offset[i]=a[i]%10;
}
for(i=4;i<=32;i++)	/*用户内存工作区从4个页面到32个页面*/

{
printf("---%2d page frames---\n",i); FIFO(i);
LRU(i);
LFU(i);
OPT(i);

}
return 0;
}

int initialize(total_pf)	/*初始化相关数据结构*/
int total_pf;	/*用户进程的内存页面数*/
{
int i; diseffect=0;
for(i=0;i<total_vp;i++)
{
pl[i].pn=i;
pl[i].pfn=INVALID;	/*置页面控制结构中的页号,页面为空*/ pl[i].counter=0;
pl[i].time=-1;	/*页面控制结构中的访问次数为0,时间为-1*/
}
for(i=0;i<total_pf-1;i++)
{
pfc[i].next=&pfc[i+1]; pfc[i].pfn=i;
}	/*建立pfc[i-1]和pfc[i]之间的链接*/ pfc[total_pf-1].next=NULL;
pfc[total_pf-1].pfn=total_pf-1;
freepf_head=&pfc[0];	/*空页面队列的头指针为pfc[0]*/

return 0;
}


int FIFO(total_pf)	/*先进先出算法*/
int total_pf;	/*用户进程的内存页面数*/
{
int i,j; pfc_type *p;
initialize(total_pf);	/*初始化相关页面控制用数据结构*/ busypf_head=busypf_tail=NULL; /*忙页面队列头,队列尾链接*/ for(i=0;i<total_instruction;i++)

{
if(pl[page[i]].pfn==INVALID)	/*页面失效*/
{
diseffect+=1;	/*失效次数*/
if(freepf_head==NULL)	/*无空闲页面*/
{
p=busypf_head->next; pl[busypf_head->pn].pfn=INVALID;
freepf_head=busypf_head;	/*释放忙页面队列的第一个页面*/
 freepf_head->next=NULL;
busypf_head=p;
}
p=freepf_head->next;	/*按FIFO方式调新页面入内存页面*/ 
freepf_head->next=NULL;
freepf_head->pn=page[i]; 
pl[page[i]].pfn=freepf_head->pfn;

if(busypf_tail==NULL) busypf_head=busypf_tail=freepf_head;
else
{
busypf_tail->next=freepf_head;	/*free页面减少一个*/ busypf_tail=freepf_head;
}
freepf_head=p;
}
}
printf("FIFO:%6.4f\n",1-(float)diseffect/320);

return 0;
}

int LRU(total_pf)	/*最近最久未使用算法*/ int total_pf;
{
int min,minj,i,j,present_time; initialize(total_pf); present_time=0;
for(i=0;i<total_instruction;i++)
{
if(pl[page[i]].pfn==INVALID)	/*页面失效*/
{
diseffect++;
if(freepf_head==NULL)	/*无空闲页面*/

{
min=32767;
for(j=0;j<total_vp;j++)	/*找出time的最小值*/ if(min>pl[j].time&&pl[j].pfn!=INVALID)
{
min=pl[j].time; minj=j;
}
freepf_head=&pfc[pl[minj].pfn];	//腾出一个单元pl[minj].pfn=INVALID;
pl[minj].time=-1; freepf_head->next=NULL;
}
pl[page[i]].pfn=freepf_head->pfn;	//有空闲页面,改为有效pl[page[i]].time=present_time;
freepf_head=freepf_head->next;	//减少一个free 页面
}
else
pl[page[i]].time=present_time;	//命中则增加该单元的访问次数

present_time++;
}
printf("LRU:%6.4f\n",1-(float)diseffect/320); return 0;
}
int OPT(total_pf)	/*最佳置换算法*/ int total_pf;
{int i,j, max,maxpage,d,dist[total_vp]; pfc_type *t;
initialize(total_pf); for(i=0;i<total_instruction;i++)
{ //printf("In OPT for 1,i=%d\n",i);
//i=86;i=176;206;250;220,221;192,193,194;258;274,275,276,277,278;
if(pl[page[i]].pfn==INVALID)	/*页面失效*/
{
diseffect++;
if(freepf_head==NULL)	/*无空闲页面*/
{for(j=0;j<total_vp;j++)
if(pl[j].pfn!=INVALID) dist[j]=32767;	/* 最大"距离" */ else dist[j]=0;
d=1;
for(j=i+1;j<total_instruction;j++)
{
if(pl[page[j]].pfn!=INVALID) dist[page[j]]=d;
d++;
}
max=-1;

for(j=0;j<total_vp;j++) if(max<dist[j])
{
max=dist[j]; maxpage=j;
}
freepf_head=&pfc[pl[maxpage].pfn]; freepf_head->next=NULL; pl[maxpage].pfn=INVALID;
}
pl[page[i]].pfn=freepf_head->pfn; freepf_head=freepf_head->next;
}
}
printf("OPT:%6.4f\n",1-(float)diseffect/320);

return 0;
}

int	LFU(total_pf)	/*最不经常使用置换法*/ int total_pf;
{
int i,j,min,minpage; pfc_type *t; initialize(total_pf);
for(i=0;i<total_instruction;i++)
{	if(pl[page[i]].pfn==INVALID)	/*页面失效*/
{ diseffect++;
if(freepf_head==NULL)	/*无空闲页面*/
{ min=32767;
for(j=0;j<total_vp;j++)
{if(min>pl[j].counter&&pl[j].pfn!=INVALID)
{
min=pl[j].counter; minpage=j;
}
pl[j].counter=0;
}
freepf_head=&pfc[pl[minpage].pfn]; pl[minpage].pfn=INVALID; freepf_head->next=NULL;
}
pl[page[i]].pfn=freepf_head->pfn;	//有空闲页面,改为有效pl[page[i]].counter++;
freepf_head=freepf_head->next;	//减少一个free 页面
}
else
pl[page[i]].counter++;

}
printf("LFU:%6.4f\n",1-(float)diseffect/320);

return 0;
}

操作系统中老师给的代码,跑出来的程序会显示效率都一样,我的理解是,因为现在的计算机运行效率太好了,得用更多的数据才能凸显出来。

你可能感兴趣的:(操作系统)