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

软件学院设计性实验报告

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

一、实验题目:页面置换算法(请求分页) 二、实验目的: 进一步理解父子进程之间的关系。 1) 理解内存页面调度的机理。 2) 掌握页面置换算法的实现方法。 3) 通过实验比较不同调度算法的优劣。 4) 培养综合运用所学知识的能力。 页面置换算法是虚拟存储管理实现的关键,通过本次试验理解内存页面调度的机制,在模拟实现FIFOLRU等经典页面置换算法的基础上,比较各种置换算法的效率及优缺点,从而了解虚拟存储实现的过程。将不同的置换算法放在不同的子进程中加以模拟,培养综合运用所学知识的能力。 三、实验内容及要求 这是一个综合型实验,要求在掌握父子进程并发执行机制和内存页面置换算法的基础上,能综合运用这两方面的知识,自行编制程序。 程序涉及一个父进程和两个子进程。父进程使用rand()函数随机产生若干随机数,经过处理后,存于一数组Acess_Series[]中,作为内存页面访问序列。两个子进程根据这个访问序列,分别采用FIFOLRU两种不同的页面置换算法对内存页面进行调度。要求: 1) 每个子进程应能反映页面置换的过程,并统计页面置换算法的命中或缺页情况。 设缺页的次数为diseffect。总的页面访问次数为total_instruction。 缺页率 = disaffect/total_instruction 命中率 = 1- disaffect/total_instruction 2)将为进程分配的内存页面数mframe 作为程序的参数,通过多次运行程序,说明FIFO算法存在的Belady现象。
实验使用一下算法 使用rand()函数随机产生页面号,用数组装入页面号,模拟页面调入内存中发生页面置换的过程。 整个过程,都是使用数组来实现每个算法,模拟队列,模拟堆栈的功能,实现每一个置换算法页面置换算法 最佳置换算法(OPT):选择永不使用或是在最长间内不再被访问(即距现在最长间才会被访问)的页面淘汰内存。用于算法评价参照。 随机置换算法 (S):产生一个取值范围在0和N-1之间的随机数,该随机数即可表示应被淘汰内存的页面。 先进先置换算法FIFO):选择最先进入内存即在内存驻留间最久的页面换到外存。 最近最久未使用置换算法LRU): 以“最近的过去”作为“最近的将来”的近似,选择最近一段间最长间未被访问的页面淘汰内存 Clock置换算法:为进入内存的页面设置一个访问位,当内存中某页被访问访问位置一,算法在选择一页淘汰,只需检查访问位,若为0,则直接换,若为1,置该访问位为0,检测内存中的下一个页面的访问位。 改进型Clock置换算法: ①从查寻指针当前位置起扫描内存分页循环队列,选择A=0且M=0的第一个页面淘汰;若未找到,转② ② 开始第二轮扫描,选择A=0且M=1的第一个页面淘汰,同将经过的所有页面访问位置0;若不能找到,转①
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

魏一鸣*

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

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

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

打赏作者

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

抵扣说明:

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

余额充值