软件学院设计性实验报告
学院:软件学院 专业:计算机科学与技术 年级/班级: 19级JAVA2班
2020—2021学年第二学期
课程名称 | 操作系统 | 指导教师 | |||
学号姓名 | 魏一鸣 | ||||
实验地点 | 计算机学院楼111实验室 | 实验时间 | 6月11日, 6月18日10:10-11:50 | ||
项目名称 | 页面置换算法 | 实验类型 | 综合性 |
- 实验目的
1 、加深对虚拟存储器的理解。
2 、熟练掌握常用页面置换算法的实现原理。
-
- OPT页面置换算法
OPT所选择被淘汰的页面是已调入内存,且在以后永不使用的,或是在最长时间内不再被访问的页面。因此如何找出这样的页面是该算法的关键。可为每个页面设置一个步长变量,其初值为一足够大的数,对于不在内存的页面,将其值重置为零,对于位于内存的页面,其值重置为当前访问页面与之后首次出现该页面时两者之间的距离,因此该值越大表示该页是在最长时间内不再被访问的页面,可以选择其作为换出页面。
-
- FIFO页面置换算法
FIFO总是选择最先进入内存的页面予以淘汰,因此可设置一个先进先出的忙页帧队列,新调入内存的页面挂在该队列的尾部,而当无空闲页帧时,可从该队列首部取下一个页帧作为空闲页帧,进而调入所需页面。
-
- LRU页面置换算法
LRU是根据页面调入内存后的使用情况进行决策的,它利用“最近的过去”作为“最近的将来”的近似,选择最近最久未使用的页面予以淘汰。该算法主要借助于页面结构中的访问时间来实现,记录一个页面上次的访问时间,因此,当须淘汰一个页面时,选择处于内存的页面中其time值最小的页面,即最近最久未使用的页面予以淘汰。
-
- LFU页面置换算法
LFU要求为每个页面配置一个计数器(即页面结构中的counter),一旦某页被访问,则将其计数器的值加1,在需要选择一页置换时,则将选择其计数器值最小的页面,即内存中访问次数最少的页面进行淘汰。
-
- NUR页面置换算法
NUR要求为每个页面设置一位访问位(该访问位仍可使用页面结构中的counter表示),当某页被访问时,其访问位counter置为1。需要进行页面置换时,置换算法从替换指针开始(初始时指向第一个页面)顺序检查处于内存中的各个页面,如果其访问位为0,就选择该页换出,否则替换指针下移继续向下查找。如果内存中的所有页面扫描完毕未找到访问位为0的页面,则将替换指针重新指向第一个页面,同时将内存中所有页面的访问位置0,当开始下一轮扫描时,便一定能找到counter为0的页面。
- 实验设备
实验机房虚拟机里的中linux系统
- 实验要求
- 在FIFO置换算法的基础上,编写实现LRU页面置换算法;
- 按如下的访问序列:12560365365604270435,
在物理块数分别为3和4时,分别调用FIFO和LRU算法,计算并输出相应的命中率。
- 实验代码
#include <stdio.h> /*初始化队列*/ void initializeList(int list[],int number){ int i; for ( i = 0; i < number; i ++) { list[i] = -1; } } /*展示队列状态*/ void showList(int list[], int number){ int i; for ( i = 0; i < number; i ++) { printf("%2d",list[i]); } printf("\n"); } /*展示当前内存状态*/ void showMemoryList(int list[],int phyBlockNum){ int i; for ( i = 0; i < phyBlockNum; i ++) { if (list[i] == -1) { break; } printf(" |%d|",list[i]); } printf("\n"); } void informationCount(int missingCount,int replaceCount,int pageNum){ printf("缺页次数:%d 缺页率:%d/%d\n",missingCount,missingCount,pageNum); double result = (double)(pageNum - missingCount)/(double)pageNum; printf("置换次数:%d 命中率:%.2f\n",replaceCount,result); } /*找到该页面下次要访问的位置*/ int getNextPosition(int currentPage,int currentPosition,int strList[],int pageNum){ int i; for ( i = currentPosition+1; i < pageNum; i ++) { if (strList[i] == currentPage) { return i; } } return 100; } /*先进先出置换算法*/ void replacePageByFIFO(int memoryList[],int phyNum,int strList[],int pageNum){ /*置换次数*/ int replaceCount = 0; /*缺页次数*/ int missingCount = 0; /*记录当前最早进入内存的下标*/ int pointer = 0; /*记录当前页面的访问情况: 0 未访问*/ int isVisited = 0; int i; for (i = 0; i < pageNum; i ++) { isVisited = 0; /*判断是否需要置换->内存已满且需要访问的页面不在内存中*/ int j; for (j = 0; j < phyNum; j ++) { if (memoryList[j] == strList[i]) { /*该页面已经存在内存中*/ /*修改访问情况*/ isVisited = 1; /*修改访问时间*/ /*展示*/ printf("%d\n",strList[i]); break; } if (memoryList[j] == -1) { /*页面不在内存中且内存未满->直接存入*/ memoryList[j] = strList[i]; /*修改访问情况*/ isVisited = 1; missingCount ++; /* 展示*/ printf("%d\n",strList[i]); showMemoryList(memoryList, phyNum); break; } } if (!isVisited) { /*当前页面还未被访问过->需要进行页面置换*/ /*直接把这个页面存到所记录的下标中*/ memoryList[pointer] = strList[i]; /*下标指向下一个*/ pointer ++; /*如果到了最后一个,将下标归零*/ if (pointer > phyNum-1) { pointer = 0; } missingCount ++; replaceCount ++; /* 展示*/ printf("%d\n",strList[i]); showMemoryList(memoryList, phyNum); } } informationCount(missingCount, replaceCount, pageNum); } /*最近最久未使用置换算法*/ void replacePageByLRU(int memoryList[],int phyNum,int strList[],int pageNum){ /*置换次数*/ int replaceCount = 0; /*缺页次数*/ int missingCount = 0; /*记录内存中最近一次访问至今的时间*/ int timeRecord[phyNum]; /*初始化*/ initializeList(timeRecord, phyNum); /*记录当前页面的访问情况: 0 未访问*/ int isVisited = 0; /*记录已经在内存中的页面数量*/ int pageCount = 0; int i; for ( i = 0; i < pageNum; i ++) { isVisited = 0; /* 时间加一*/ int p; for (p = 0; p < pageCount; p ++) { if (memoryList[p] != -1) { timeRecord[p] ++; } } /*是否需要置换*/ int j; for ( j = 0; j < phyNum; j ++) { if (memoryList[j] == strList[i]) { /*该页面已经存在内存中*/ /*修改访问情况*/ isVisited = 1; /*重置访问时间*/ timeRecord[j] = -1; /*展示*/ printf("%d\n",strList[i]); break; } if (memoryList[j] == -1) { /*页面不在内存中且内存未满->直接存入*/ memoryList[j] = strList[i]; pageCount ++; /*修改访问情况*/ isVisited = 1; /*修改访问时间*/ timeRecord[j] ++; missingCount ++; /*展示*/ printf("%d\n",strList[i]); showMemoryList(memoryList, phyNum); break; } } if (!isVisited) { /* 需要置换*/ /*1.遍历时间记录表,寻找最久未访问的页面所在的内存下标*/ int max = 0; int k; for ( k = 0; k < phyNum; k ++) { if (timeRecord[max] < timeRecord[k]) { max = k; } } /*2.将该位置的页面换出*/ memoryList[max] = strList[i]; timeRecord[max] = -1; missingCount ++; replaceCount ++; /*展示*/ printf("%d\n",strList[i]); showMemoryList(memoryList, phyNum); } } informationCount(missingCount, replaceCount, pageNum); } int main(int argc, const char * argv[]) { /*物理块的数量*/ int phyBlockNum; printf("请输入物理块数量:\n"); scanf("%d",&phyBlockNum); /*生成内存队列*/ int memoryList[phyBlockNum]; /*初始化内存状态*/ initializeList(memoryList, phyBlockNum); showMemoryList(memoryList,phyBlockNum); /*页面数量*/ int pageNum; printf("请输入要访问的页面总数:\n"); scanf("%d",&pageNum); /*保存页面号引用串*/ int pageNumStrList[pageNum]; printf("请输入要访问的页面号:\n"); int i; for (i = 0; i < pageNum; i ++) { scanf("%d",&pageNumStrList[i]); } showList(pageNumStrList, pageNum); int chose; while (1) { printf("请选择所需的置换算法:\n"); printf("1.FIFO 2.LRU 3.退出\n"); scanf("%d",&chose); switch (chose) { case 1: showList(pageNumStrList, pageNum); replacePageByFIFO(memoryList, phyBlockNum, pageNumStrList, pageNum); /*重新初始化内存*/ initializeList(memoryList , phyBlockNum); break; case 2: showList(pageNumStrList, pageNum); replacePageByLRU(memoryList, phyBlockNum, pageNumStrList, pageNum); /*重新初始化内存*/ initializeList(memoryList, phyBlockNum); break; default: return 0; break; } } return 0; }
- 结果分析与总结
物理块数为3
调用FIF0算法结果:
调用LRU算法结果:
物理块为4
调用FIFO算法结果:
调用LRU算法结果: