📄 ~
字号:
#include<stdio.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <cmath>
#define total_struction 320
#define total_vp 32
typedef struct /*页结构*/
{
int pn,pfn, counter,time;
}pl_type; /* PN为页号,PFN为页面号,counter为一个周期内访问页面次数,time为访问时间*/
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;
/*pfc[total_vp]定义用户进程虚页控制结构,frepf_head为空页面头指针 ,busypf_head为忙页面头指针,busypf_tail为忙页面尾指针 */
int diseffect;
int a[total_struction], page[total_struction], offset[total_struction];
void initialize(int); /*初始化函数,给每个相关的页面赋值*/
void FIFO(int); /*计算FIFO算法缺页率*/
void LFU(int); /*计算FLFU算法缺页率*/
void srand (unsigned int seed);
int main( )
{
int s,i,j;
srand(10*getpid()); /*由于每次运行时进程号不同,故可用来作为初始化随机数序列的“种子”*/
s=(float)319*rand( )/32767/32767/2+1;/*计算第一条指令的地址s*/
for(i=0;i<320;i+=4) /*产生指令地址序列*/
{
a[i]=s; /*地址s存入a[i]*/
a[i+1]=a[i]+1; /*地址s+1存入a[i+1],表示顺序执行s的下一条指令*/
a[i+2]=(float)a[i]*rand( )/32767/32767/2; /*计算s的一条任意的前地址指令的地址s',并存入a[i+2],表示向前跳转*/
a[i+3]=a[i+2]+1; /*地址s'+1存入a[i+1],表示顺序执行s'的下一条指令*/
s=(float)(318-a[i+2])*rand( )/32767/32767/2+a[i+2]+2; /*计算s'的一条任意的后地址指令的地址s,表示向后跳转*/
}
/*(1)end*/
for (i=0;i<320;i++) /*将指令序列变换成页地址流*/
{
page[i]=a[i]/10; /*计算地址a[i]的页号*/
offset[i]=a[i]%10; /*计算地址a[i]的页内便移地址*/
}
/*(2)end*/
for(i=4;i<=32;i++) /*用户内存工作区从4个页面到32个页面*/
{
printf("---%2d page frames---\n",i);
FIFO(i); /*先入先出算法*/
LFU(i); /*最少访问页淘汰算法*/
printf("\n");
}
/*(3)end*/
}
void FIFO(total_pf) /*先进先出页面置换算法*/
int total_pf; /*用户进程的内存页面数*/
{
int i,j;
pfc_type *p;
initialize(total_pf); /*初始化相关页面控制用数据结构*/
busypf_head=busypf_tail=NULL;/*已调入内存的页面队列头、尾指针初始化*/
for(i=0;i<320;i++)
{
if(pl[page[i]].pfn==-1) /*如果页面失效(缺页)*/
{
diseffect+=1; /*计算失效次数*/
if(freepf_head==NULL) /*无空闲页面*/
{
p=busypf_head->next;
pl[busypf_head->pn].pfn=-1;/*换出忙页面队列的第一个页面*/
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;
busypf_tail=freepf_head; /*新调入的页挂在忙队列的尾上*/
}
freepf_head=p;/*修改空闲队列指针*/
}
}
printf("FIFO:%6.4f\n",1-(float)diseffect/320);
}
void LFU(total_pf) /*最不经常使用页面置换法*/
int total_pf;
{
int i,j,min,minpage;
pfc_type *t;
initialize(total_pf); /*初始化相关页面控制用数据结构*/
for(i=0;i<320;i++)
{ if(pl[page[i]].pfn==-1) /*如果页面失效(缺页)*/
{ diseffect++;
if(freepf_head==NULL) /*无空闲页面*/
{ min=32767;
for(j=0;j<32;j++)
{ if(min>pl[j].counter&&pl[j].pfn!=-1)
{min=pl[j].counter; minpage=j;}
pl[j].counter=0;
}
freepf_head=&pfc[pl[minpage].pfn];
pl[minpage].pfn=-1;
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);
}
void initialize(total_pf) /*初始化相关数据结构*/
int total_pf; /*用户进程分得的内存页面数*/
{ int i;
diseffect=0; /*缺页次数初值为0*/
for(i=0;i<32;i++)
{
pl[i].pn=i; /*置每一页结构中的页号为i*/
pl[i].pfn=-1; /*置每一页结构中的页面为-1,表示还没调入内存*/
pl[i].counter=0; /*置每一页结构中的访问次数为0*/
}
for(i=0;i<total_pf-1;i++)
{
pfc[i].next=&pfc[i+1];
pfc[i].pfn=i;
} /*将分给进程的total_pf个块链接起来*/
pfc[total_pf-1].next=NULL;
pfc[total_pf-1].pfn=total_pf-1;
freepf_head=&pfc[0]; /*空页面队列的头指针为pfc[0]*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -