【页面置换】页面置换算法的设计

页面置换算法的模拟实现

一、设计目的和要求
1.设计目的
《操作系统实验》课程设计是学习完《操作系统原理》及实验课程后进行的一次较全面的综合练习。其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。
2.基本要求:
(1)选择课程设计题目中的一个课题,独立完成。
(2)良好的沟通和合作能力
(3)充分运用前序课所学的软件工程、程序设计、数据结构等相关知识
(4)充分运用调试和排错技术
(5)简单测试驱动模块和桩模块的编写
(6)查阅相关资料,自学具体课题中涉及到的新知识。
(7)课题完成后必须按要求提交课程设计报告,格式规范,内容详实。

设计内容及步骤

1.根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么。
2.根据实现的功能,划分出合理的模块,明确模块间的关系。
3.编程实现所设计的模块。
4.程序调试与测试。采用自底向上,分模块进行,即先调试低层函数。能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果;
5.结果分析。程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。

需求分析

1.设计一个虚拟存储区和内存工作区,编程序演示下述算法的具体实现过程,并计算访问命中率。要求设计主界面以灵活选择某算法,且以下算法都要实现
(1)最佳淘汰算法(OPT)
(2)最近最少访问页面算法(LRU)
2.要有体现算法比较的程序输出,比如:缺页率和页面置换次数等。
3.采用固定分配局部置换,且可以在程序中实现块数重新分配。
具有抖动判断和Belady异常判断机制

概要设计

根据设计要求实现对页面置换算法的模拟以及
进程状态转换的模拟。
根据自己输入 物理块数量,访问页面总数,要访问的页面号,
2.然后选择所需的置换算法 OPT,LRU 二选一. 计算过程,并得出 缺页次数,缺页率,置换次数,命中率的结果;
3.进行虚拟存储算法设计分析。

主要数据结构

2.主要数据结构
void initializeList(int list[],int number)//根据队列来判断当前内存状态,进一步决定页面的换进换出
void showList(int list[], int number)//显示队列状态,清晰地看出每一步之后的结果队列状态
void informationCount(int missingCount,int replaceCount,int pageNum)//对缺页次数的判断,很重要
void replacePageByOPT(int memoryList[],int phyNum,int strList[],int pageNum)//最佳算法函数
void replacePageByLRU(int memoryList[],int phyNum,int strList[],int pageNum)//LRU算法函数

算法描述

(1)最佳置换算法optimal OPT
选择永不使用或是在最长时间内不再被访问(即距现在最长时间才会被访问)的页面淘汰出内存。
OPT属于理想化算法,具有最好性能(对于固定分配页面方式,本法可保证获得最低的缺页率),但实际上却无法实现,主要用于算法评价参照。
(2)最近最久未使用置换算法 LRU
以“最近的过去”作为“最近的将来”的近似,选择最近一段时间最长时间未被访问的页面淘汰出内存。适用于各种类型的程序,性能较好,但需要较多的硬件支持。

3.算法流程
1.OPT
例如下述页面走向:6,7,5,2,6,7,3,6,7,5,2,3 当分配的内存物理块数量为 3时
先放入6,7,5,当放入2的时候,显而易见,最长时间不需要访问的页面就是5,那么先将5给置换掉

当放入6的时候,已经存在,不需要置换

当放入7的时候,已经存在,不需要置换

当放入3的时候,最长时间不需要访问的页面就是2,那么先将2给置换掉

当放入6的时候,已经存在,不需要置换

当放入7的时候,已经存在,不需要置换

当放入5的时候,最长时间不需要访问的页面就是6和7,可以将其中一页置换掉

当放入2的时候,最长时间不需要访问的页面就是5和7或者5和6,可以将其中一页置换掉

最后当放入3的时候,已经存在,不需要置换

6 7 5 2 6 7 3 6 7 5 2 3
1 6 6 6 6 6 6 6 6 6 5 5 5
2 7 7 7 7 7 7 7 7 7 2 2
3 5 2 2 2 3 3 3 3 3 3
R Y Y Y Y N N Y N N Y Y N
2.LRU与上面分析类似
7 0 1 2 0 3 0 4
7 7 7 2 2 4
0 0 0 0 1
1 1 3 3

详细设计

1.设计中要解决的关键问题
1.1 页面置换算法是在当进程运行过程中,若其要访问的页面不在内存且内存已满时,要决定将哪个页面换出的算法。常见的页面置换算法包括最佳置换、先进先出置换、最近最久未使用置换和Clock置换等。本次的实验实现的算法包括最佳置换算法(OPT)、最近最久未使用算法(LRU)。
1.2 页面置换算法涉及到一些概念,我们需要了解并解决它们: 缺页率:当需要访问的页面不在内存时称为缺页,此时需要将页面调入内存。缺页率就是要访问的页面不在内存中的概率。因此缺页率=缺页次数/要访问的页面总数。需要注意的是,缺页的时候不一定需要进行页面置换(如果内存还没满,直接将页面调入内存即可)。
置换率:置换就是将旧页面调出内存,新页面调进内存,即新页面代替旧页面的过程。置换率就是需要进行页面置换的概率。所以置换率=置换次数/要访问的页面总数。
命中率:就是要访问的页面恰好在内存中的概率。可以发现(缺页率+命中率=1)。 最佳置换算法
最佳置换算法,就是所选择内存中以后永远不再使用,或者是在未来最长的一段时间内不再被访问的页面来换出。用这种算法可以保证获得最低的缺页率,最低的置换次数,因此效率最高。然而在实际情况中,我们是无法知道哪个页面是未来最长时间内不再被访问的,所以实际上它是无法实现的。
最近最久未使用算法,是选择当前内存中,最久没有被访问的页面来换出。它是希望通过过去页面访问的情况,来预测未来页面的访问情况,但是页面过去与未来的走向之间并没有必然的联系,因此它的效率也不是十分高。
2.对于内存状态的判断,以及页面置换之后队列的相应变化情况
3.判断 当前页面还没访问过
内存已满且当前访问不在内存中->进行置换
.寻找到最晚才被访问到的页面
.将该位置的页面换出
4.对于LRU算法我们还需要记录相应的访问时间
创建一个对应时间表
遍历时间记录表,寻找最久未访问的页面所在的
将满足条件的置换出去
2.主要功能代码及代码主要注释
1.队列初始化工作,与内存状态
//初始化队列
void initializeList(int list[],int number){
for (int i = 0; i < number; i ++) {
list[i] = -1;
}
}
//展示队列状态
void showList(int list[], int number){
for (int i = 0; i < number; i ++) {
printf("%2d",list[i]);
}
printf("\n");
}
//展示当前内存状态
void showMemoryList(int list[],int phyBlockNum){
for (int 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);
}
2.OPT算法
//最佳置换算法
void replacePageByOPT(int memoryList[],int phyNum,int strList[],int pageNum){

//置换次数
int replaceCount = 0;
//缺页次数
int missingCount = 0;

//记录在内存的物理块的下一次访问位置
int nextPosition[phyNum];
//初始化
initializeList(nextPosition, phyNum);

//记录当前页面的访问情况: 0 未访问
int isVisited;

for (int i = 0; i < pageNum; i ++) {
    isVisited = 0;
    //判断是否需要置换->内存已满且需要访问的页面不在内存中

for (int j = 0; j < phyNum; j ++) {
if (memoryList[j] == strList[i]) {
//该页面已经存在内存中
//记录下一次访问它的位置
nextPosition[j] = getNextPosition(memoryList[j], i, strList, pageNum);

            //修改访问情况
            isVisited = 1;
            
            //展示
            printf("%d\n",strList[i]);
            break;
        }
        if (memoryList[j] == -1) {
            //页面不在内存中且内存未满->直接存入
            memoryList[j] = strList[i];
            nextPosition[j] = getNextPosition(memoryList[j], i, strList, pageNum);
             missingCount ++;
            
            //修改访问情况
            isVisited = 1;
            
            //展示
            printf("%d\n",strList[i]);
            showMemoryList(memoryList, phyNum);
            break;
        }
    }
    
    if (!isVisited) {
        
        //当前页面还没访问过
        //内存已满且当前访问不在内存中->进行置换
        //1.寻找到最晚才被访问到的页面
        int max = 0;
        for (int k = 1; k < phyNum; k ++) {
            if (nextPosition[max] < nextPosition[k]) {
                max = k;
            }
        }
        //2.将该位置的页面换出
        memoryList[max] = strList[i];
        nextPosition[max] = getNextPosition(memoryList[max], i, strList, pageNum);
        
        missingCount ++;
        replaceCount ++;
        
        //展示
        printf("%d\n",strList[i]);
        showMemoryList(memoryList, phyNum);
    }
}
informationCount(missingCount, replaceCount,pageNum);

}
3.LRU算法
//最近最久未使用置换算法
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;
for (int i = 0; i < pageNum; i ++) {
    isVisited = 0;
    //时间加一
    for (int p = 0; p < pageCount; p ++) {
        if (memoryList[p] != -1) {
            timeRecord[p] ++;
        }
    }
    
    //是否需要置换
    for (int 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;
        for (int 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);
}

测试结果及分析

详细分析见源码注释内容
OPT算法:根据未来实际使用情况将未来的近期里不用的页替换出去。这种算法是用来评价期它替 换算法好坏的标准。不可能实现。所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。无Belady异常。
LRU算法:选择近期最少访问的页作为被替换页。,无Belady异常。
通过多次的不同访问序列,得到的缺页情况也不一样,
1.OPT算法实现结果
在这里插入图片描述
在这里插入图片描述

2.LRU算法实现结果

在这里插入图片描述
在这里插入图片描述

源码见

##评论区留言嗷、、、

最后

总结
1.同一种算法,对于不同的访问序列,其缺页率是不同的。
2.总的来看,最佳置换算法的缺页率是最低的。剩下的算法中,页面缓冲算法的缺页率要低于其他置换算法。改进型clock算法稍微好于先进先出算法和最近最久未使用算法。先进先出算法和最近最久未使用算法性能相近。总的来看,性能(缺页率)如下。
最佳置换算法>最近最久未使用算法

七.用户使用说明
1.程序运行平台 Dev-C++
2.程序执行路径:任何,内存够就可以,内存可以自定义途径
3.程序执行时要点
1)、需先生成物理块与页面个数,
2)、依次输入你所要访问的页面号
3)、之后根据你的选择来使用不同的算法

  • 20
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Kewen_and_Ulrikh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值