操作系统页面置换算法实验 页面置换算法实验

软件学院设计性实验报告

学院:软件学院        专业:计算机科学与技术   年级/班级: 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系统

  • 实验要求
  1. 在FIFO置换算法的基础上,编写实现LRU页面置换算法;
  2. 按如下的访问序列: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算法结果:

  • 17
    点赞
  • 125
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魏一鸣*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值