1、 . 实验五 存储管理 一、实验目的 1 、加深对操作系统存储管理的理解 2 、能过模似页面调试算法,加深理解操作系统对存的高度管理 二、 总的设计思想、环境语言、工具等总的设计思想: 1、编写函数计算并输出下述各种算法的命中率 ① OPT页面置换算法 OPT所选择
2、被淘汰的页面是已调入存,且在以后永不使用的,或是在最长时间不再被访问的页面。因此如找出这样的页面是该算法的关键。可为每个页面设置一个步长变量,其初值为一足够大的数,对于不在存的页面,将其值重置为零,对于位于存的页面,其值重置为当前访问页面与之后首次出现该页面时两者之间的距离,因此该值越大表示该页是在最长时间不再被访问的页面,可以选择其作为换出页面。 ② FIFO页面置换算法 FIFO总是选择最先进入存的页面予以淘汰,因此可设置一个先进先出的忙页帧队列,新调入存的页面挂在该队列的尾部,而当无空闲页帧时,可从该队列首部取下一个页帧作为空闲页帧,进而调入所需页面。 ③ LRU页面置换算法 L
3、RU是根据页面调入存后的使用情况进展决策的,它利用“最近的过去〞作为“最近的将来〞的近似,选择最近最久未使用的页面予以淘汰。该算法主要借助于页面构造中的访问时间time来实现,time记录了一个页面上次的访问时间,因此,当须淘汰一个页面时,选择处于存的页面中其time值最小的页面,即最近最久未使用的页面予以淘汰。 ④ LFU页面置换算法 LFU要求为每个页面配置一个计数器〔即页面构造中的counter〕,一旦某页被访问,那么将其计数器的值加1,在需要选择一页置换时,那么将选择其计数器值最小的页面,即存中访问次数最少的页面进展淘汰。 ⑤ NUR页面置换算法 NUR要求为每个页面设置一位访
4、问位〔该访问位仍可使用页面构造中的counter表示〕,当某页被访问时,其访问位counter置为1。需要进展页面置换时,置换算法从替换指针开场〔初始时指向第一个页面〕顺序检查处于存中的各个页面,如果其访问位为0,就选择该页换出,否那么替换指针下移继续向下查找。如果存中的所有页面扫描完毕未找到访问位为0的页面,那么将替换指针重新指向第一个页面,同时将存中所有页面的访问位置0,当开场下一轮扫描时,便一定能找到counter为0的页面。 2、 在主函数中生成要求的指令序列,并将其转换成页地址流;在不同的存容量下调用上述函数使其计算并输出相应的命中率。 环境语言:Linux下的GNU 编译环境
5、 三、数据构造与模块说明 程序中用到的数据构造、类型定义及主要的函数原型如下: 1、 数据构造 (1) 页面构造 typedef struct{ int pn,pfn, counter, time; }pl_type; pl_type pl[total_vp]; 其中pn为页面号〔页号〕,pfn为页帧号〔物理块号〕,counter为一个期访问该页面的次数,time为访问时间;pl[total_vp]为页面构造数组,由于共有320条指令,每页可装入10条指令,因此虚页长total_vp的值为32。 〔2〕页帧控制构造 struct pfc_struct{ int
6、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]定义用户进程的页帧控制构造数组,在该实验中,用户存工作区是动态变化的,最多可到达用户进程的虚页数目,即32个物理块。 *freepf_head为空闲页帧头的指针 *busypf_head为忙页帧头的指针 *busypf_tail忙页帧尾的指针 2、 变量定义 (1) int a
7、[total_instruction]:指令流数组 (2) int diseffect:页面失效次数 (3) int page[total_instruction]:每条指令所属页面号 (4) int offset[total_instruction]:每页装入10条指令后取模运算得出的页偏移地址 (5) int total_pf:用户进程的存页帧数 3、 主要函数 (1) void initialize(int):初始化函数 该函数主要对页面构造数组pl和页帧构造数组pfc进展初始化,如置页面构造中的页面号pn,初始化页帧号pfn为空,访问次数counter为0,访问时间ti
8、me为-1;同样对页帧数组进展初始化,形成一个空闲页帧队列。 (2) void OPT(int):计算使用最正确页面算法时的命中率 (3) void FIFO(int):计算使用先进先出页面置换算法时的命中率 (4) void LRU(int):计算使用最近最久未使用页面置换算法时的命中率 (5) void LFU(int): 计算使用最少使用置换算法时的命中率 (6) void NUR(int): 计算使用最近未使用置换算法时的命中率 四、主要算法的设计与实现 void FIFO(int total_pf) /*先进先出页面置换算法*/ { int i,j
9、
pfc_type *p;
initialize(total_pf);
busypf_head=busypf_tail=NULL;
for(i=0;i
10、面作为换出页面 freepf_head=busypf_head; freepf_head->next=NULL; busypf_head=p; //忙页帧头指针后移 } p=freepf_head->next; //有空闲页帧 freepf_head->next=NULL; freepf_head->pn=page[i]; /* 将所需页面调入空闲页帧 */ pl[page[i]].pfn=freepf_head->pfn; if(busypf_tail==NULL) /* 假设忙页帧队列为空,那么将其头尾指针都指向刚调入页面所在的页帧 */ busypf_head=
11、busypf_tail=freepf_head; else{ //否那么,将刚调入页面所在的页帧挂在忙页帧队列尾部 busypf_tail->next=freepf_head; busypf_tail=freepf_head; } freepf_head=p; //空闲页帧头指针后移 } } printf("FIFO:%6.4f ",1-(float)diseffect/320); } void LRU(int total_pf)/*最近最久未使用页面置换算法*/ { int i,j; int min,minj,present_time;
12、
initialize(total_pf);
present_time=0;
for(i=0;i
13、 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]].ti
14、me=present_time;//命中那么修改该单元的访问时间
present_time++;
}
printf("LRU:%6.4f ",1-(float)diseffect/320);
}
void NUR(int total_pf)/* 最近未使用页面置换算法 */
{
int i,j,dp,cont_flag,old_dp;
initialize(total_pf);
dp=0;
for(i=0;i 15、
if(freepf_head==NULL)/*无空闲页帧*/
{
cont_flag=TRUE;
old_dp=dp;
while(cont_flag)
{
if(pl[dp].counter==0&&pl[dp].pfn!=INVALID)
cont_flag=FALSE; //找到位于存且未被访问的页面
else
{
dp++;
if(dp==total_vp) dp=0; //将替换指针重新指向第一个页面
if(dp==old_dp)
{/* 假设存中所有页面扫描完毕未找到访问位为0的页面,将存中所有页面的访问位置0 */
for 16、j=0;j 17、period==0) //清零期到,将所有访问位清零
{
for(j=0;j 18、/*页面失效*/
{
diseffect++;
if(freepf_head==NULL)/*无空闲页面*/
{
for(j=0;j 19、ion;j++)
{
if(pl[page[j]].pfn!=INVALID && dist[page[j]]==32767)
dist[page[j]]=d;
d++;
}
max=-1;
//查找dist变量值最大的页面作为换出页面
for(j=0;j 20、INVALID;
}
pl[page[i]].pfn=freepf_head->pfn;//有空闲页面,改为有效
freepf_head=freepf_head->next;//减少一个free 页面
}
}
printf("OPT:%6.4f ",1-(float)diseffect/320);
}
void LFU(int total_pf) /* 最少使用页面置换算法 */
{
int i,j,min,minpage;
initialize(total_pf);
for(i=0;i 21、].pfn==INVALID) //页面失效
{
diseffect++;
if(freepf_head==NULL) //无空闲页帧
{
min=32767;
for(j=0;j 22、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 ",1-(float)diseffect/320);
}
五、运行结果
本实验的运行结 23、果如以下图所示〔以OPT、FIFO、LRU为例〕:
从上述结果可知,随着存页面数的增加,三种算法的访问命中率逐渐增大。在存页面数为4~25个页面之间时,三种算法的命中率大致在56%至88%之间变化,但是,OPT算法和其他两种算法之间的差异一般在6~12个百分点左右。在存页面为25~32个页面时,由于用户进程的所有指令根本上都已装入存,从而命中率增加较大,各种算法之间的差异不大。
比较上述三种算法,OPT算法的命中率最高,LRU算法和FIFO算法的命中率那么较为接近。
六、 总结
经过测试结果完全正常。经过编写和学习让我对操作系统面的知识更深一步的得到了理解和稳固。让我在今后的学习中可以更好的去理解和体会。
. .word.zl.






