页面置换算法实验(yss)
实验目的:
(1)设计和实现最佳(Optimal)置换算法、先进先出(FIFO)置换算法、最近最久未使用(Least Recently Used)置换算法、改进型Clock置换算法、页面缓冲算法(PBA);
(2)通过页面访问序列随机发生器实现对上述算法的测试及性能比较。
课题假设前提:
(1)模拟的虚拟内存的地址为16位,页面大小为1K,则最大虚拟物理块为64;
(2)模拟的物理内存有32K;
(3)页表用整数数组或结构数组来表示;
(4)页面访问序列串是一个整数序列,整数的取值范围为0到N - 1。页面访问序列串中的每个元素p表示对页面p的一次访问。
相关概念:
工作集:
多数程序都显示出高度的局部性,也就是说,在一个时间段内,一组页面被反复引用。这组被反复引用的页面随着时间的推移,其成员也会发生变化。有时这种变化是剧烈的,有时这种变化则是渐进的。我们把这组页面的集合称为工作集。
缺页率:
缺页率 = 缺页中断次数/页面访问次数
页面访问序列随机生成说明:(符合局部访问特性的随机生成算法)
(1)确定虚拟内存的尺寸N,工作集的起始位置p,工作集中包含的页数e,工作集移动率m(每处理m个页面访问则将起始位置p +1),以及一个范围在0和1之间的值t;
(2)生成m个取值范围在p和p + e间的随机数,并记录到页面访问序列串中;
(3)生成一个随机数r,0 ≤ r ≤ 1;
(4)如果r < t,则为p生成一个新值,否则p = (p + 1) mod N;
(5)如果想继续加大页面访问序列串的长度,请返回第2步,否则结束。
代码:
int SequenceCreation()//创建页面访问序列
{
int N,P,e,m,i=0,j=0,k=0,judge=0;
float t,r;
printf("请输入虚拟内存大小:\n");
scanf("%d",&N);
while(N>64)
{
printf("虚拟内存限制最大页数为64,请重新输入虚拟内存大小:\n");
scanf("%d",&N);
}
printf("请输入工作集的起始位置(P<N):\n");
scanf("%d",&P);
printf("请输入工作集包含的页数(e<N):\n");
scanf("%d",&e);
printf("请输入工作集移动率(m<N):\n");
scanf("%d",&m);
srand((unsigned)time(NULL));
t = 0.5;
do
{
for(j=0; j<m; j++)
{
record[j+k] = ((rand()%e)+P)%N;
}
k+=m;
r = rand()/32767.0;
if(r < t)
{
P = rand()%N;
}
else
{
P = (P+1)%N;
}
printf("如果想继续加大页面访问序列串的长度,请输入:1,否则输入0;\n");
printf("此时访问序列串的长度为:%d\n",k);
scanf("%d",&judge);
}
while(judge==1);
printf("页面访问序列串为:\n");
for(i = 0; i < k; i++)
{
printf("%d ",record[i]);
}
printf("\n");
return k;//返回页面访问序列串的长度
}
最佳置换算法
基本思想:
它是由Belady于1966年提出的一种理论上的算法。其所选择的被淘汰页面,将是以后永不使用的或许是在最长(未来)时间内不再被访问的页面。采用最佳置换算法,通常可保证获得最低的缺页率。但由于人目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,便可以利用此算法来评价其它算法。
评价:
理想化算法,具有最好性能(对于固定分配页面方式,本法可保证获得最低的缺页率),但实际上却难于实现,故主要用于算法评价参照。
代码:
int OPT()//最佳置换算法
{
int i;
missNum = 0;
curmemory = 0;
printf("最佳置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
if (Search(page[i].num, memory) < 0)//若在内存中没有找到该页面
{
//找出未来最长时间内不再被访问的页面
int tem;
int opt = 0;
int k;
for (k = 0; k < memoryNum; k++)
{
if (memory[k].num == -1)
{
curmemory = k;
break;
}
tem = 0; //页面k在未来tem时间内不会出现
int j;
for (j = i+1; j < pageNum; j++)
{
if (page[j].num == memory[k].num)
{
if (tem > opt)
{
opt = tem;
curmemory = k;
}
break;
}
else tem++;
}
if (j == pageNum)
{
opt = tem;
curmemory = k;
}
}
missNum++;
memory[curmemory].num = page[i].num;
print(memory);
}
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
先进先出置换算法
基本思想:
选择最先进入内存即在内存驻留时间最久的页面换出到外存。
进程已调入内存的页面按进入先后次序链接成一个队列,并设置替换指针以指向最老页面。
评价:
简单直观,但不符合进程实际运行规律,性能较差,故实际应用极少。
代码:
int FIFO()//先进先出页面置换算法
{
int i;
missNum = 0;
printf("先进先出页面置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
if (Search(page[i].num, memory)<0)//若在内存中没有找到该页面
{
missNum++;
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum; //找出最先进入内存的页面
}
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
最近最久未使用置换算法
基本思想:
以“最近的过去”作为“最近的将来”的近似。该算法赋予每一个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当需要淘汰一个页面时,选择现有页面中t值最大的,即最近最久未使用的页面予以淘汰。
评价:
适用于各种类型的程序,性能较好,但需要较多的硬件支持。
代码:
int LRU()//最近最久未使用置换算法
{
int i;
missNum = 0;
curmemory = 0;
printf("最近最久未使用置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
int rec=Search(page[i].num, memory);
if (rec < 0) //若在内存中没有找到该页面
{
missNum++;
int j;
for (j = 0; j<memoryNum; j++) //找出最近最久未使用的页面
if (memory[j].time == -1)
{
curmemory = j;
break;
}
else if (memory[j].time > memory[curmemory].time)
curmemory = j;
memory[curmemory].num = page[i].num;
memory[curmemory].time = 0;
print(memory);
}
else memory[rec].time = 0;
int j;
for (j = 0; j<memoryNum; j++) //内存中的所有页面等待时间+1
if (memory[j].num != -1)
memory[j].time++;
}//end for
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
改进型Clock置换算法
基本思想:
除考虑页面的使用情况外,还需再增加一个因素,即置换代价,选择页面换出时,既要是未使用过的页面,又要是未被修改过的页面。把同时满足这两个条件的页面最为首选淘汰的页面。由访问位A,修改位M可以组合成四种类型的页面
1类(A=0,M=0)该页面最近既未被访问,又未被修改,最佳淘汰页
2类(A=0,M=1)该页面最近未被访问,但已被修改,并不是最好的淘汰页。
3类(A=1,M=0)该页面最近已被访问,但未被修改,该页有可能再被访问。
4类(A=1,M=1)该页面最近已被访问且被修改,该页面可能再被访问
执行过程:
1,从指针的当前位置开始,循环扫描队列,寻找第一类页面,将遇到的第一个页面淘汰。第一遍扫描不改变其访问位A
2,如果第一步失败,开始第二轮扫描。需寻找第二类页面,将遇到的第一个页面淘汰,第二遍扫描时将其访问位都置为0
3,如果第二步也失败,则将指针返回到开始位置,将访问位复0,重复第一步,或者第二步。
评价:
与简单Clock算法相比,可减少磁盘的I/O操作次数,但淘汰页的选择可能经历多次扫描,故实现算法自身的开销增大。
代码:
int Clock()//改进型Clock置换算法
{
int i;
int seek=0;
missNum = 0;
curmemory = 0;
printf("改进型Clock置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
seek = 0;
int rec=Search(page[i].num, memory);
if (rec < 0) //若在内存中没有找到该页面
{
int j;
missNum++;
for (j = 0; j<memoryNum; j++) //随机选择修改位
{
memory[j].M = rand()%2;
}
do
{
for (j = 0; j<memoryNum; j++) //寻找是否有空闲物理块
{
if (memory[j].num == -1)
{
curmemory = j;
seek = 1;
memory[j].num = 0;
break;
}
}
if(seek != 1)
{
for (j = 0; j<memoryNum; j++) //寻找最近即未被访问,又为被修改的页面
{
if (memory[j].A == 0 && memory[j].M == 0)
{
curmemory = j;
seek = 1;
break;
}
}
if(seek != 1)
{
for (j = 0; j<memoryNum; j++) //寻找最近即未被访问,但已被修改的页面
{
if (memory[j].A == 0 && memory[j].M == 1)
{
curmemory = j;
seek = 1;
break;
}
memory[j].A = 0;
}
}
}
}
while(seek == 0);
}
memory[curmemory].num = page[i].num;
print(memory);
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
页面缓冲算法PBA
基本思想:
页面缓冲算法(PBA):Page Buffering Algorithm,需要设置一个缓冲区。该算法将一个被淘汰的页面放入两个链表中的一个,即如果页面未被修改,就将它放入空闲链表中;否则便放入到已修改的链表中。页面在内存中并不做物理上的移动,而是将页表中的表项移到上述两个链表之一。空闲链表和修改页面链表。
评价:
利用这种方式可以使被修改的页面和未被修改的页面都仍然保留在内存中。当该进程以后再次访问这些页面时,只花费较小的开销,是这些页面又返回到该进程的驻留集中。当被修改的页面数达到一定数目时,如64个页面,再将它们一起写回到磁盘上,从而显著的减少磁盘I/O次数。
代码:
int PBA()//页面缓冲算法(PBA)
{
int i,j,k;
int length = 3;//空闲页面链表
missNum = 0;
Pro *memory2; //空闲页面链表
memory2 = (Pro*)malloc(sizeof(Pro)*length);
for (i = 0; i<length; i++)
{
page[i].num = -1;
page[i].time = -1;
page[i].A = 0;
page[i].M = 0;
}
printf("页面缓冲算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
if (Search(page[i].num, memory)<0 && Search(page[i].num, memory2)<0)//若在内存及空闲链表中没有找到该页面
{
missNum++;
if(memory[curmemory].num == -1)
{
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum; //找出最先进入内存的页面
}
else
{
if(memory[curmemory].M == 0)
{
for (j = 0; j<length; j++)
{
if(memory2[j].num == -1)
{
memory2[j].num = memory[curmemory].num;
memory2[j].M = memory[curmemory].M;
break;
}
}
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum; //找出最先进入内存的页面
}
else
{
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum;
}
}
}
else
{
if (Search(page[i].num, memory2)>=0)
{
for (j = 0; j<length; j++)
{
if(memory2[j].num == page[i].num)
{
for(k=j; k>0; k--)
{
memory2[k].num = memory2[k-1].num;
memory2[k].M = memory2[k-1].M;
}
memory2[0].num = memory[curmemory].num;
}
}
}
}
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
free(memory2);
return 0;
}
总代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct item
{
int num; //页号
int time; //等待时间,LRU算法会用到这个属性
int A; //访问位,Clock算法会用到这个属性
int M; //修改位,Clock算法会用到这个属性
} Pro;
Pro *page; //作业页面集
Pro *memory; //内存页面集
int record[10000]; //页面访问序列
int pageNum; //系统分配给作业的主存中的页面数
int memoryNum; //可用内存页面数
int curmemory; //调入内存中的页面个数
int missNum; //缺页次数
float missRate; //缺页率
//子函数
int SequenceCreation(); //创建页面访问序列
int OPT(); //最佳置换算法
int FIFO(); //先进先出页面置换算法
int LRU(); //最近最久未使用置换算法
int Clock(); //改进型Clock置换算法
int PBA(); //页面缓冲算法(PBA)
void print(Pro *page1); //打印当前主存中的页面
int Search(int num1, Pro *memory1); //在页面集memory1中查找num1,如果找到,返回其在memory1中的下标,否则返回-1
int main(void)//主函数
{
int i;
char c; //得到用户的输入字符,来选择相应的置换算法
pageNum = SequenceCreation(); //创建页面访问序列
printf("输入系统分配内存页面数:\n");
scanf("%d", &memoryNum);
page = (Pro*)malloc(sizeof(Pro)*pageNum);
memory = (Pro*)malloc(sizeof(Pro)*memoryNum);
for (i = 0; i<pageNum; i++)
{
page[i].num = record[i];
page[i].time = 0;
page[i].A = 0;
page[i].M = 0;
}
do
{
for (i = 0; i<memoryNum; i++) //初始化内存中页面
{
memory[i].num = -1; //页面为空用-1表示
memory[i].time = -1;
memory[i].A = 0;
memory[i].M = 0;
}
printf("请根据提示选择以下页面置换算法:\n");
printf(" o:最佳(Optimal)置换算法\n");
printf(" f:先进先出(FIFO)置换算法\n");
printf(" l:最近最久未使用(Least Recently Used)置换算法\n");
printf(" c:改进型Clock置换算法\n");
printf(" p:页面缓冲算法(PBA)\n");
printf("*****请选择操作类型(o,f,l,c,p),按其它键结束******\n");
getchar();
scanf("%c", &c);
curmemory = 0;
if (c == 'o') //最佳(Optimal)置换算法
{
OPT();
}
if (c == 'f') //先进先出(FIFO)置换算法
{
FIFO();
}
if (c == 'l') //最近最久未使用(Least Recently Used)置换算法
{
LRU();
}
if (c == 'c') //改进型Clock置换算法
{
Clock();
}
if (c == 'p') //页面缓冲算法(PBA)
{
PBA();
}
}
while (c == 'o' || c == 'f' || c == 'l' || c == 'c' || c == 'p');
free(page);
free(memory);
return 0;
}
int FIFO()//先进先出页面置换算法
{
int i;
missNum = 0;
printf("先进先出页面置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
if (Search(page[i].num, memory)<0)//若在内存中没有找到该页面
{
missNum++;
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum; //找出最先进入内存的页面
}
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
int OPT()//最佳置换算法
{
int i;
missNum = 0;
curmemory = 0;
printf("最佳置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
if (Search(page[i].num, memory) < 0)//若在内存中没有找到该页面
{
//找出未来最长时间内不再被访问的页面
int tem;
int opt = 0;
int k;
for (k = 0; k < memoryNum; k++)
{
if (memory[k].num == -1)
{
curmemory = k;
break;
}
tem = 0; //页面k在未来tem时间内不会出现
int j;
for (j = i+1; j < pageNum; j++)
{
if (page[j].num == memory[k].num)
{
if (tem > opt)
{
opt = tem;
curmemory = k;
}
break;
}
else tem++;
}
if (j == pageNum)
{
opt = tem;
curmemory = k;
}
}
missNum++;
memory[curmemory].num = page[i].num;
print(memory);
}
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
int LRU()//最近最久未使用置换算法
{
int i;
missNum = 0;
curmemory = 0;
printf("最近最久未使用置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
int rec=Search(page[i].num, memory);
if (rec < 0) //若在内存中没有找到该页面
{
missNum++;
int j;
for (j = 0; j<memoryNum; j++) //找出最近最久未使用的页面
if (memory[j].time == -1)
{
curmemory = j;
break;
}
else if (memory[j].time > memory[curmemory].time)
curmemory = j;
memory[curmemory].num = page[i].num;
memory[curmemory].time = 0;
print(memory);
}
else memory[rec].time = 0;
int j;
for (j = 0; j<memoryNum; j++) //内存中的所有页面等待时间+1
if (memory[j].num != -1)
memory[j].time++;
}//end for
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
int Clock()//改进型Clock置换算法
{
int i;
int seek=0;
missNum = 0;
curmemory = 0;
printf("改进型Clock置换算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
seek = 0;
int rec=Search(page[i].num, memory);
if (rec < 0) //若在内存中没有找到该页面
{
int j;
missNum++;
for (j = 0; j<memoryNum; j++) //随机选择修改位
{
memory[j].M = rand()%2;
}
do
{
for (j = 0; j<memoryNum; j++) //寻找是否有空闲物理块
{
if (memory[j].num == -1)
{
curmemory = j;
seek = 1;
memory[j].num = 0;
break;
}
}
if(seek != 1)
{
for (j = 0; j<memoryNum; j++) //寻找最近即未被访问,又为被修改的页面
{
if (memory[j].A == 0 && memory[j].M == 0)
{
curmemory = j;
seek = 1;
break;
}
}
if(seek != 1)
{
for (j = 0; j<memoryNum; j++) //寻找最近即未被访问,但已被修改的页面
{
if (memory[j].A == 0 && memory[j].M == 1)
{
curmemory = j;
seek = 1;
break;
}
memory[j].A = 0;
}
}
}
}
while(seek == 0);
}
memory[curmemory].num = page[i].num;
print(memory);
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
return 0;
}
int PBA()//页面缓冲算法(PBA)
{
int i,j,k;
int length = 3;//空闲页面链表
missNum = 0;
Pro *memory2; //空闲页面链表
memory2 = (Pro*)malloc(sizeof(Pro)*length);
for (i = 0; i<length; i++)
{
page[i].num = -1;
page[i].time = -1;
page[i].A = 0;
page[i].M = 0;
}
printf("页面缓冲算法页面置换情况: \n");
for (i = 0; i<pageNum; i++)
{
if (Search(page[i].num, memory)<0 && Search(page[i].num, memory2)<0)//若在内存及空闲链表中没有找到该页面
{
missNum++;
if(memory[curmemory].num == -1)
{
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum; //找出最先进入内存的页面
}
else
{
if(memory[curmemory].M == 0)
{
for (j = 0; j<length; j++)
{
if(memory2[j].num == -1)
{
memory2[j].num = memory[curmemory].num;
memory2[j].M = memory[curmemory].M;
break;
}
}
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum; //找出最先进入内存的页面
}
else
{
memory[curmemory].num = page[i].num;
print(memory);
curmemory = (curmemory + 1) % memoryNum;
}
}
}
else
{
if (Search(page[i].num, memory2)>=0)
{
for (j = 0; j<length; j++)
{
if(memory2[j].num == page[i].num)
{
for(k=j; k>0; k--)
{
memory2[k].num = memory2[k-1].num;
memory2[k].M = memory2[k-1].M;
}
memory2[0].num = memory[curmemory].num;
}
}
}
}
}
missRate = (float)missNum / pageNum;
printf("缺页次数:%d 缺页率: %f\n\n", missNum, missRate);
free(memory2);
return 0;
}
void print(Pro *memory1)//打印当前的页面
{
int j;
for (j = 0; j<memoryNum; j++)
printf("%d ", memory1[j].num);
printf("\n");
}
int Search(int num1, Pro *memory1)//在页面集memory1中查找num1,如果找到,返回其在memory1中的下标,否则返回-1
{
int j;
for (j = 0; j<memoryNum; j++)
{
if (num1 == memory1[j].num)
{
memory[j].M = 1;
return j;
}
}
return -1;
}
int SequenceCreation()//创建页面访问序列
{
int N,P,e,m,i=0,j=0,k=0,judge=0;
float t,r;
printf("请输入虚拟内存大小:\n");
scanf("%d",&N);
while(N>64)
{
printf("虚拟内存限制最大页数为64,请重新输入虚拟内存大小:\n");
scanf("%d",&N);
}
printf("请输入工作集的起始位置(P<N):\n");
scanf("%d",&P);
printf("请输入工作集包含的页数(e<N):\n");
scanf("%d",&e);
printf("请输入工作集移动率(m<N):\n");
scanf("%d",&m);
srand((unsigned)time(NULL));
t = 0.5;
do
{
for(j=0; j<m; j++)
{
record[j+k] = ((rand()%e)+P)%N;
}
k+=m;
r = rand()/32767.0;
if(r < t)
{
P = rand()%N;
}
else
{
P = (P+1)%N;
}
printf("如果想继续加大页面访问序列串的长度,请输入:1,否则输入0;\n");
printf("此时访问序列串的长度为:%d\n",k);
scanf("%d",&judge);
}
while(judge==1);
printf("页面访问序列串为:\n");
for(i = 0; i < k; i++)
{
printf("%d ",record[i]);
}
printf("\n");
return k;//返回页面访问序列串的长度
}
实验结果:
符合局部访问特性的随机生成算法相关参数:
生成的随机页面访问序列(200):
2 0 0 2 0 1 1 3 0 2 14 16 13 13 12 12 16 14 15 13 15 14 13 16 15 17 16 14 13 14 50 49 50 50 50 46 48 49 47 48 6 6 6 5 5 8 7 5 8 6 6 7 8 6 9 8 7 5 9 9 47 44 47 44 46 47 44 47 48 48 47 45 47 48 46 47 49 47 45 46 47 44 47 47 44 45 43 45 45 46 48 48 48 44 45 44 47 47 45 46 47 49 45 45 46 45 46 45 45 48 50 50 48 47 49 49 50 48 49 49 24 28 27 24 25 26 26 27 27 25 28 25 28 27 27 25 29 25 28 26 29 26 26 26 29 30 28 26 30 30 27 27 28 28 30 31 29 28 28 28 9 8 12 12 12 12 8 10 12 11 21 21 22 18 20 19 19 19 21 19 23 23 22 22 21 22 19 23 21 20 0 0 2 63 1 3 0 2 63 2
生成的随机页面访问序列(2000):
0 4 3 9 0 0 8 7 3 5 6 4 1 0 3 1 3 4 3 8 3 10 7 3 10 8 9 6 2 3 6 3 3 8 2 7 1 8 3 10 32 41 39 33 39 38 40 32 39 41 32 34 39 35 40 36 38 35 34 36 42 35 40 40 42 37 38 40 33 33 42 42 40 34 42 35 38 42 40 35 44 44 51 44 43 47 45 46 52 46 50 50 48 44 46 52 43 43 43 51 49 48 51 47 53 51 51 50 51 53 51 52 46 51 52 49 48 47 49 49 52 50 53 51 53 47 49 54 49 55 55 48 49 54 55 51 48 53 54 52 48 57 49 55 57 50 52 53 50 52 51 50 56 48 57 55 55 51 55 55 55 54 58 56 56 51 53 50 58 53 57 57 57 50 53 50 56 54 50 54 15 14 13 10 14 19 11 12 17 14 17 11 16 14 15 10 12 18 13 17 13 20 17 20 11 18 18 12 17 11 14 12 14 11 17 15 14 20 16 12 50 52 54 54 54 56 54 59 50 55 53 57 53 55 58 52 53 56 58 54 55 54 52 55 59 52 56 52 59 56 56 53 57 0 55 0 54 57 0 52 1 53 57 59 54 0 52 59 58 56 1 55 56 59 52 56 52 55 52 56 55 57 1 58 2 53 54 56 53 56 57 55 2 56 53 55 2 2 55 53 1 3 57 0 56 55 55 54 3 56 59 1 2 54 58 0 54 59 1 54 56 1 58 59 59 55 57 1 55 3 58 3 55 4 59 3 1 4 56 59 10 13 16 11 15 7 12 8 8 14 7 14 8 12 12 15 7 16 11 13 5 3 9 3 6 8 9 10 1 8 2 2 3 2 10 6 7 10 5 7 5 3 2 10 4 10 5 8 4 3 7 4 3 6 11 9 9 3 2 8 12 7 5 8 12 5 4 10 6 12 12 12 4 11 3 11 7 7 8 8 13 13 6 13 4 11 10 8 6 13 12 5 7 13 10 6 9 12 7 9 20 18 17 15 16 15 18 12 20 15 11 15 18 14 14 12 14 20 20 12 3 58 4 6 4 57 4 6 2 58 57 2 58 2 0 58 0 6 3 5 26 34 31 27 30 34 28 30 26 34 28 28 28 29 29 26 35 32 33 26 33 36 38 36 34 31 31 38 32 32 30 38 29 37 31 38 38 32 38 35 48 42 41 43 48 47 48 44 47 46 45 43 39 45 43 39 48 39 42 48 20 29 29 22 25 29 25 23 28 28 28 26 27 23 23 29 26 20 25 21 26 29 26 23 27 22 21 28 28 23 22 25 22 28 24 26 23 23 25 21 56 4 55 4 0 3 3 1 58 0 4 56 59 1 58 57 1 1 55 0 16 16 9 9 14 13 16 11 7 13 16 10 14 15 12 13 15 10 15 14 11 17 14 13 14 14 13 9 16 8 13 11 9 8 11 11 17 9 13 16 14 12 14 11 9 16 17 12 12 12 13 13 16 16 17 14 11 16 15 9 20 27 25 26 25 19 24 23 26 24 25 21 21 22 28 21 24 21 26 28 27 29 29 20 21 28 29 29 25 20 21 24 20 22 29 23 26 26 24 27 24 23 25 22 20 22 21 24 25 22 20 23 25 18 21 26 22 18 21 20 24 27 25 26 25 20 25 24 19 25 24 21 28 21 19 21 20 19 27 23 3 4 6 7 3 3 1 9 3 2 4 0 1 0 0 4 9 4 1 1 58 58 1 5 58 58 0 1 58 57 57 1 2 57 57 4 2 58 1 5 59 4 5 5 6 0 57 4 2 6 4 6 58 2 0 5 4 59 5 4 58 59 5 3 0 58 2 0 4 5 58 2 6 7 58 58 58 0 58 58 1 59 59 2 2 59 4 1 5 59 2 1 5 4 2 1 7 7 59 0 0 8 4 0 1 7 6 5 1 8 2 1 8 5 1 6 7 9 1 3 0 54 54 1 57 54 56 59 53 58 54 0 57 59 55 55 0 59 0 56 17 15 16 24 24 16 15 19 20 23 17 20 19 16 20 21 16 21 19 22 49 45 45 44 50 48 50 51 51 42 44 47 47 49 49 48 51 49 45 47 49 51 55 47 49 53 56 53 54 50 48 50 49 50 53 49 52 56 48 48 52 53 54 51 50 57 51 54 55 54 52 50 48 48 53 54 53 54 50 53 52 54 49 58 56 49 56 51 51 57 58 54 55 57 55 54 52 51 55 51 51 57 58 59 53 50 55 58 52 58 52 51 57 56 51 51 56 55 58 50 8 6 10 8 4 7 6 7 4 11 6 9 9 6 3 4 7 9 4 10 3 9 12 4 6 11 6 4 5 10 12 8 3 5 9 3 11 3 6 9 7 1 4 7 1 4 3 8 4 2 0 3 2 8 7 59 6 4 2 8 0 59 5 4 58 5 2 0 58 56 58 58 1 0 3 58 4 2 59 1 28 37 37 37 31 34 34 37 28 36 36 28 32 30 30 33 30 37 30 34 28 28 32 23 32 30 32 25 24 23 23 23 32 27 28 30 32 31 32 23 25 29 32 28 27 25 31 32 26 24 29 30 32 30 27 30 32 31 26 32 58 58 1 0 59 1 0 1 2 2 58 59 1 59 58 5 2 5 1 3 2 59 1 3 4 57 1 3 4 1 6 58 4 3 5 57 2 3 5 59 6 7 10 12 13 11 6 15 9 9 9 13 15 11 14 10 11 10 12 9 7 11 13 16 13 9 10 9 9 11 13 13 11 11 14 14 13 13 11 16 13 12 13 11 10 16 12 16 14 9 13 13 10 13 17 10 16 9 8 17 10 10 10 11 15 14 14 9 9 18 11 10 13 9 9 17 16 12 18 12 15 17 11 13 16 10 13 14 19 17 18 18 13 14 13 18 19 17 17 11 32 33 35 36 37 32 36 37 29 28 29 36 34 34 28 28 31 37 35 32 30 33 38 29 31 32 33 34 30 29 33 37 34 31 35 35 32 30 36 38 39 34 38 33 35 37 34 32 37 31 39 32 32 31 31 39 33 36 31 38 31 40 38 33 31 34 40 35 32 31 36 32 31 37 37 38 32 36 32 34 58 57 56 59 3 59 0 1 58 2 0 0 56 3 3 2 57 57 1 0 56 59 58 3 2 1 1 57 58 57 59 1 56 4 0 59 0 4 4 0 57 0 57 56 5 0 3 57 58 5 2 2 5 59 0 3 59 2 58 5 33 39 40 34 33 38 37 32 40 41 39 35 35 33 38 33 38 32 40 36 39 40 38 39 35 40 34 41 42 40 35 36 42 36 42 36 39 41 36 37 56 1 58 54 57 59 55 1 58 53 57 59 0 0 2 53 54 55 58 54 5 57 5 58 56 4 4 56 4 59 59 2 2 58 58 58 59 2 5 58 29 25 27 33 34 33 28 28 34 27 32 33 32 34 34 34 30 31 29 30 3 9 2 5 7 10 3 6 7 2 2 5 3 5 4 8 10 10 9 3 6 8 6 7 12 8 11 8 7 3 12 5 8 10 10 9 6 7 5 7 1 57 52 56 57 54 0 57 55 0 52 56 0 58 0 58 55 59 52 55 52 49 49 54 49 51 48 53 48 55 55 53 53 53 51 49 55 54 47 47 51 56 56 52 50 49 55 56 48 52 52 55 50 50 49 55 50 54 48 49 57 49 50 52 54 49 54 55 54 52 53 55 55 50 55 54 53 53 55 57 54 51 50 53 49 54 50 55 55 55 54 51 49 57 56 54 53 54 56 54 50 58 52 54 51 59 51 50 53 52 58 58 58 59 51 59 57 51 50 55 52 58 53 56 56 54 53 0 56 57 52 57 57 52 54 52 59 56 53 59 36 45 40 40 40 43 44 45 40 40 44 44 39 38 43 40 41 44 40 37 27 26 20 20 21 20 20 24 26 19 20 21 27 26 23 20 25 22 19 18 24 24 24 23 25 21 19 23 26 19 19 20 27 26 25 20 21 27 20 19 11 12 19 17 16 12 12 19 18 13 20 19 11 12 19 15 13 13 20 11 45 37 42 40 42 39 46 38 38 38 44 38 39 43 38 46 42 42 45 40 8 11 8 7 6 11 12 11 5 7 4 9 10 12 12 13 5 12 10 5 8 10 13 12 9 12 13 6 5 13 12 12 10 13 11 7 7 10 12 12 15 15 7 14 14 9 12 7 14 15 10 9 14 12 6 13 15 11 8 14 26 27 26 33 32 32 34 29 29 32 33 26 30 28 32 35 30 30 27 33 47 47 38 43 46 39 45 41 41 43 47 46 47 42 43 38 45 39 41 39 44 42 46 39 46 46 40 39 46 44 39 46 48 42 44 47 45 40 43 40 46 43 42 45 42 43 41 43 43 48 40 40 49 40 45 46 45 41 40 43 42 42 43 43 38 39 38 40 38 37 36 35 35 38 37 39 37 37 42 36 11 12 13 12 13 12 12 13 7 5 11 10 7 12 13 9 4 12 10 9 14 5 11 13 10 10 12 11 10 7 8 14 14 10 10 8 6 13 13 10
因数据集较大,不放实验截图。
当系统分配内存页面数为20时:
最佳置换算法页面缺页次数:240 缺页率: 0.120000;
先进先出页面置换算法缺页次数:386 缺页率: 0.193000;
最近最久未使用置换算法缺页次数:367 缺页率: 0.183500;
改进型Clock置换算法缺页次数:1029 缺页率: 0.514500;
页面缓冲算法缺页次数:373 缺页率: 0.186500;
性能测评及问题说明
测试不同的页面访问序列及不同的虚拟内存尺寸,并从缺页率、算法开销等方面对各个算法进行比较。
可多次通过代码进行实验测试,通过上述数据集200和2000,可得实验分析:
(1)最佳置换算法缺页率最低,但实际情况不能实现。
(2)当数据集较小时,最佳置换算法、先进先出页面置换算法、最近最久未使用置换算法、页面缓冲算法差别不大。
(3)改进型Clock置换算法缺页次数最多,缺页率最高。
(4)当数据集较大时,页面缓冲算法缺页率就比较低了。
(5)不同的页面访问序列及不同的虚拟内存尺寸,都可能影响算法的缺页率。
如需了解更多知识,可点击以下链接:
https://github.com/yuanshaosui/OS/tree/master/页面置换算法