第5次实验14281147王飞.docx

上传人:b****8 文档编号:30418782 上传时间:2023-08-14 格式:DOCX 页数:42 大小:111.52KB
下载 相关 举报
第5次实验14281147王飞.docx_第1页
第1页 / 共42页
第5次实验14281147王飞.docx_第2页
第2页 / 共42页
第5次实验14281147王飞.docx_第3页
第3页 / 共42页
第5次实验14281147王飞.docx_第4页
第4页 / 共42页
第5次实验14281147王飞.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

第5次实验14281147王飞.docx

《第5次实验14281147王飞.docx》由会员分享,可在线阅读,更多相关《第5次实验14281147王飞.docx(42页珍藏版)》请在冰豆网上搜索。

第5次实验14281147王飞.docx

第5次实验14281147王飞

实验五页面置换算法

1.实验目的

设计和实现最佳置换算法、先进先出置换算法、最近最久未使用置换算法、页面缓冲置换算法;通过页面访问序列随机发生器实现对上述算法的测试及性能比较。

2.实验基础知识及背景说明

(1)请求分页虚拟内存管理

请求分页虚拟内存管理是建立在基本分页基础上的,为了能支持虚拟存储器功能,而增加了请求调页功能和置换功能。

(2)工作集

多数程序都显示出高度的局部性,也就是说,在一个时间段内,一组页面被反复引用。

这组被反复引用的页面随着时间的推移,其成员也会发生变化。

有时这种变化是剧烈的,有时这种变化则是渐进的。

我们把这组页面的集合称为工作集

(3)缺页率

缺页中断次数/总的页面访问次数

3.实验前提说明

(1)页表用整数数组或结构数组来表示

(2)页面访问序列串是一个整数序列,整数的取值范围为0到N-1。

页面访问序列串中的每个元素p表示对页面p的一次访问

(3)符合局部访问特性的随机生成算法

a.确定虚拟内存的尺寸N,工作集的起始位置p,工作集中包含的页数e,工作集移动率m(每处理m个页面访问则将起始位置p+1),以及一个范围在0和1之间的值t

b.生成m个取值范围在p和p+e间的随机数,并记录到页面访问序列串中

c.生成一个随机数r,0≤r≤1

d.如果r

e.如果想继续加大页面访问序列串的长度,请返回第2步,否则结束

4.实验算法介绍

(1)最佳置换算法

最佳置换算法的主要思想是,在发生页面替换时,被替换的对象应该满足,在以后的页面访问中,该对象不会再次被访问或者较晚被访问。

是一种理想化算法,具有最好性能(对于固定分配页面方式,本法可保证获得最低的缺页率),但实际上却难于实现,故主要用于算法评价参照

(2)先进先出置换算法

先进先出置换算法的主要思想是,在发生页面替换时,被替换的对象应该是最早进入内存的。

(3)最近最久未使用置换算法

最近最久未使用置换算法的主要思想是,在发生页面替换时,被替换的页面应该满足,在之前的访问队列中,该对象截止目前未被访问的时间最长

(4)改进型Clock置换算法

改进型Clock置换算法的主要思想是,在每次页面替换时,总是尽可能地先替换掉既未被访问又未被修改的页面。

(5)页面缓冲算法

设立空闲页面链表和已修改页面链表采用可变分配和基于先进先出的局部置换策略,并规定被淘汰页先不做物理移动,而是依据是否修改分别挂到空闲页面链表或已修改页面链表的末尾,空闲页面链表同时用于物理块分配,当已修改页面链表达到一定长度如Z个页面时,一起将所有已修改页面写回磁盘,故可显著减少磁盘I/O操作次数

5.相关数据结构设计

根据各个算法的特点,程序实现的过程中用到的数据结构主要有以下两种

(1)数组:

定义的时候利用指针定义,然后根据全局变量block设定的给进程分配的物理内存的块数动态分配内存。

一旦完成内存分配,不再改变数组的大小。

用到数组结构来实现的算法程序有:

最佳置换算法,先进先出置换算法,最近最久未使用置换算法,改进型置换算法。

(2)队列:

为单向队列,队列长度仍然由全局变量指定。

用到队列的算法程序有:

先进先出置换算法。

队列结点元素的结构体如下

typedefstructnode

{

intnum;//页号

node*next;//下一个结点页面

}Node,*pNode;

typedefstructqueue

{

intn;//总的结点数

pNodefront;//队首指针

pNoderear;//队尾指针

}Queue,*pQueue;

(3)链表:

主要是将装入内存的页块串联起来。

用到链表的算法程序:

页面缓冲算法。

链表结点元素的结构体如下

structLNode

{

intdata;//页号

intflag;//访问位

intmodify;//修改位

LNode*next;

};

structLink

{

intnum;//当前链表上的结点数

LNode*next;

};

6.主要函数功能说明

(1)全局共享函数

voidinitMemo();//初始化存储空间,主要是设置分配空间的大小

voidgenerate();//生成访问序列

boolisInMemo(intn);//指定页号是否已经在内存中

(2)最佳置换算法

voidoptimal(intn);//访问一个页面,执行一次最佳置换算法

voidtestOptimal();//算法实现函数

(3)先进先出置换算法

voidinitQueue(pQueueq);//初始化队列

voidpush(pQueueq,intnum);//队列中加入新的页面结点

voidpop(pQueueq);//将页面移出内存

voiddestroy(pQueueq);//销毁队列

boolfindInQueue(pQueueq,intnum);//查找页面是否已经调入内存

voidgenerate();//生成访问序列

voidfifoTest();//每访问一个页面,执行一次算法

voidfifo(pQueueq,intnum);//先进先出置换算法实现函数

(4)最近最久未使用置换算法

voidLRU(intn);//每访问一个新的页面,执行一次LRU算法

voidtestLRU();//LRU算法实现函数

(5)改进型clock置换算法

voidupdated_Clock(intn);//改进型clock算法实现函数

voidtest_Clock();//每访问一个新的页面,执行一次算法

(6)页面缓冲算法

boolisInNodes(intn);//页面是否已经在链表中

voidaddToLink(intdata,inttype);//页面添加到已修改页面链表和空闲链表上

voidemptyIdle();//将空闲链表上的所有页面送出内存

voidemptyModi();//将已修改页面链表上所有的链表送出内存

voidPBA(intn);//PBA算法实现函数

7.程序运行

每个算法实现的代码量不同,以及不同算法使用的数据结构有差别,为了不至于程序过于臃肿庞大,所以所有的算法总共是在三个程序实现的(具体代码如8附录所示).其中,最佳置换算法,LRU算法,改进型clock置换算法是在experiment5.cpp中实现的,先进先出置换算法是在FIFO.cpp中实现的,页面缓冲置换算法是在PBA.cpp中实现的。

为了便于对比,程序中会先用genenrate()函数产生大小为32的访问序列,然后在每种算法下运行。

测试过程如下:

(1)利用generate函数产生访问序列如下

access[32]={2,3,3,7,2,8,3,7,9,7,10,8,12,11,8,8,61,61,3,61,62,60,2,60,3,62,62,3,3,4,2,62}

(2)各算法执行结果如下

a.最佳置换算法(局部)

可以看到,32个页面,有12个页面发生了缺页,缺页率为0.375

b.先进先出算法

可以看到,32个页面,有15个页面发生了缺页,缺页率为0.46875

c.最近最久未使用置换(LRU)算法

可以看到,32个页面,有18个页面发生了缺页,缺页率为0.5625

d.改进型clock置换算法

可以看到,32个页面,有14个页面发生了缺页,缺页率为0.4375

e.页面缓冲置换算法

可以看到,32个页面,有15个页面发生了缺页,缺页率为0.46875

 

(3)利用genenrate()函数再生成几个访问序列,记录每个序列下,每种算法的缺页情况,最终整理得到如下统计表格:

 

注:

访问序列的长度始终为32,默认初始分配给每种算法的内存空间块数为3

置换算法

最佳置换算法

先进先出置换算法

最近最久未使用算法

改进型clock置换算法

页面缓冲置换算法

测试序列1

缺页数

12

15

18

14

15

缺页率

0.375

0.46875

0.5625

0.4375

0.46875

测试序列2

缺页数

10

14

15

13

11

缺页率

0.3125

0.4375

0.46875

0.40625

0.34375

测试序列3

缺页数

13

16

15

16

14

缺页率

0.40625

0.5

0.46875

0.5

0.4375

使用同样的访问序列,改变分配给每种算法的的内存空间块数为5,得到实验结果如下

置换算法

最佳置换算法

先进先出置换算法

最近最久未使用算法

改进型clock置换算法

页面缓冲置换算法

测试序列1

缺页数

7

11

9

10

9

缺页率

0.21875

0.3475

0.28125

0.3125

0.28125

测试序列2

缺页数

7

9

9

10

11

缺页率

0.21875

0.28125

0.28125

0.3125

0.34375

测试序列3

缺页数

9

12

11

11

11

缺页率

0.28125

0.375

0.34375

0.34375

0.34375

从上图表观察可以得到如下结论:

(1)同一种算法,对于不同的访问序列,其缺页率是不同,会有所变化。

(2)总的来看,最佳置换算法的缺页率是最低的,这一点是毋庸置疑的。

剩下的集中算法中,页面缓冲算法的缺页率要低于其他置换算法。

改进型clock算法稍微好于先进先出算法和最近最久未使用算法。

先进先出算法和最近最久未使用算法性能相近。

总的来看,性能(缺页率)如下。

最佳置换算法>页面缓冲置换算法>改进型clock置换算法>最近最久未使用算法>=先进先出置换算法。

(3)对比内存块数为3和内存块数为5两种情况下的同一序列下的同一,可以发现,算法的缺页率还跟分配的内存块数有关系,分配的内存块数越多,缺页率越低。

这与直观感受是一致的,即导入内存的块数越多,发生缺页的可能性就越小。

8.附录(程序代码)

PBA.cpp

#include"stdafx.h"

#include"stdio.h"

#include"stdlib.h"

#include"time.h"

#defineM32//物理内存块数

#defineN64//虚拟内存块数

structLNode

{

intdata;

intflag;//访问位

intmodify;//修改位

LNode*next;

};

structLink

{

intnum;//当前链表上的结点数

LNode*next;

};

voidgenerate();//生成访问序列

boolisInNodes(intn);//

voidaddToLink(intdata,inttype);

voidemptyIdle();

voidemptyModi();

voidPBA(intn);

intsize=3;

intp;//工作集的起始位置

inttable[32];//物理内存,每一个元素代表一个页面

intaccess[32];//访问序列

intmemo[3]={-1,-1,-1};

intlost=0;//没找到的页面数

intindex=0;//指示当前下标

LNode*nodes;//改进型Clock置换算法用到的数据结构

Linkidle;

Linkmodified;

int_tmain(intargc,_TCHAR*argv[])

{

inti=0,j=0;

generate();

printf("页面缓冲置换算法(PBA)\n");

idle.num=0;

idle.next=NULL;

modified.num=0;

modified.next=NULL;

nodes=(LNode*)malloc(size*sizeof(LNode));

for(i=0;i

{

nodes[i].data=-1;

nodes[i].flag=0;

nodes[i].modify=0;

nodes[i].next=NULL;

}

for(i=0;i<32;i++)

{

PBA(i);

for(j=0;j

{

printf("%d",nodes[j].data);

}

printf("\n");

}

printf("页面缓冲置换算法(PBA)缺页率:

%f%d\n",lost/32.0,lost);

getchar();

getchar();

return0;

}

 

voidgenerate()

{

srand((unsigned)time(NULL));//用时间做种,每次产生随机数不一样

p=rand()%64;

intm=8,e=8;

inti,j;

doublet;

t=rand()%10/10.0;

for(i=0;i<4;i++)

{

for(j=i*m;j<(i+1)*m;j++)

{

access[j]=(p+rand()%e)%64;

}

doubler=(rand()%10)/10.0;

if(r

{

p=rand()%64;

}

else

{

p=(p+1)%64;

}

}

}

boolisInNodes(intn)

{

inti;

for(i=0;i<3;i++)

{

if(nodes[i].data==access[n])

{

returntrue;

}

}

returnfalse;

}

LNode*isinLinks(intn)

{

LNode*p,*q;

p=idle.next;

q=NULL;

while(p)

{

if(p->data==access[n])

{

if(q!

=NULL)

{

q->next=p->next;

p->next=NULL;

idle.num--;

break;

}

else

{

idle.next=NULL;

}

}

q=p;

p=p->next;

}

if(p==NULL)

{

p=modified.next;

while(p!

=NULL)

{

if(p->data==access[n])

{

if(p==modified.next)

{modified.next=p->next;}

else

{

q->next=p->next;

p->next=NULL;

modified.num--;

}

if(modified.num==0)

{modified.next=NULL;}

break;

}

q=p;

p=p->next;

}

}

returnp;

}

 

voidPBA(intn)

{

if(isInNodes(n))

{

printf("已装入内存\n");

}

else

if(index==size)

{

LNode*p;

if((p=isinLinks(n))!

=NULL)

{

nodes=(LNode*)realloc(nodes,(size+1)*sizeof(LNode));

nodes[size].data=p->data;

nodes[size].flag=p->flag;

nodes[size].modify=p->modify;

nodes[size].next=p->next;

free(p);

size++;

index++;

}

else

{

lost++;//缺页

if(nodes[n%3].modify==1)

{

addToLink(nodes[n%3].data,1);

}

else

{

addToLink(nodes[n%3].data,0);

}

nodes[n%3].data=access[n];

nodes[n%3].flag=1;

nodes[n%3].next=NULL;

if(rand()%10<4)

{

nodes[n%3].modify=0;

}

else

{

nodes[n%3].modify=1;

}

}

}

else

{

nodes[index].data=access[n];

nodes[index].flag=1;

nodes[index].next=NULL;

if(rand()%10<4)

{

nodes[index].modify=1;

}

else

{

nodes[index].modify=0;

}

index++;

}

}

voidaddToLink(intdata,inttype)

{

LNode*p;

LNode*q;

q=(LNode*)malloc(sizeof(LNode));

q->data=data;

q->flag=1;

if(type==1)

{

q->modify=1;

p=modified.next;

}

else

{

q->modify=0;

p=idle.next;

}

q->next=NULL;

if(p==NULL)

{

if(type==0)

{

idle.next=q;

}

else

{

modified.next=q;

}

}

else

{

while(p)

{

if(p->next==NULL)

{

p->next=q;

break;

}

else

{

p=p->next;

}

}

}

if(type==0)

{

idle.num+=1;

if(idle.num==10)

{

emptyIdle();

}

}

else

{

modified.num+=1;

if(modified.num==10)

{

emptyModi();

}

}

}

voidemptyIdle()

{

LNode*p;

p=idle.next;

while(p)

{

idle.next=p->next;

free(p);

p=idle.next;

}

idle.num=0;

}

voidemptyModi()

{

LNode*p;

p=modified.next;

while(p)

{

modified.next=p->next;

free(p);

p=modified.next;

}

modified.num=0;

}

 

FIFO.cpp

//FIFO.cpp:

定义控制台应用程序的入口点。

#include"stdafx.h"

#include"stdio.h"

#include"stdlib.h"

#include"time.h"

typedefstructnode

{

intnum;

node*next;

}Node,*pNode;

typedefstructqueue

{

intn;

pNodefront;

pNoderear;

}Queue,*pQueue;

 

voidinitQueue(pQueueq);

voidpush(pQueueq,intnum);

voidpop(pQueueq);

voiddestroy(pQueueq);

boolfindInQueue(pQueueq,intnum);

voidgenerate();

voidfifoTest();

voidfifo(pQueueq,intnum);

intaccess[32];//访问序列

intsize=3;//给进程分配的内存的大小

intlost=0;//缺页数

int_tmain(intargc,_TCHAR*argv[])

{

//generate();

fifoTest();

getchar();

getchar();

return0;

}

voidinitQueue(pQueueq)

{

q->rear=(pNode)malloc(sizeof(Node));

if(q->rear==NULL)

{

printf("failed\n");

}

else

{

q->front=q->rear;

q->rear->next=NULL;

q->front->next=NULL;

q->n=0;

}

}

voidpush(pQueueq,intnum)

{

pNodep=(pNode)malloc(sizeof(Node));

if(p==NULL)

{

printf("failed");

}

else

{

p->next=NULL;

p->num=num;

if(q->front==q->rear)

{

q->front->next=p;

q->rear=p;

}

else

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 职业教育 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1