广州大学操作系统实验三 内存管理

广州大学操作系统实验三 内存管理

一、实验目的
1、了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
2、了解程序设计技术和内存泄露的原因
二、 实验内容
1、模拟实现请求页式存储管理的几种基本页面置换算法(1)最佳淘汰算法(OPT)(2)先进先出的算法(FIFO)(3)最近最久未使用算法(LRU))
三、 实验要求
(1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成:A:50%的指令是顺序执行的B:25%的指令是均匀分布在前地址部分C:25%的指令是均匀分布在后地址部分具体的实施方法是:A:在[0,319]的指令地址之间随机选取一起点mB:顺序执行一条指令,即执行地址为m+1的指令C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’D:顺序执行一条指令,其地址为m’+1E:在后地址[m’+2,319]中随机选取一条指令并执行F:重复步骤A-E,直到320次指令(2)将指令序列变换为页地址流设:页面大小为1K;用户内存容量4页到32页;用户虚存容量为32K。在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:第 0 条-第 9 条指令为第0页(对应虚存地址为[0,9])第10条-第19条指令为第1页(对应虚存地址为[10,19])………………………………第310条-第319条指令为第31页(对应虚存地址为[310,319])按以上方式,用户指令可组成32页。

四、三种置换算法原理
页面置换算法的分类
1.最佳置换算法(OPT)
(1)实现原理:每次选择未来长时间不被访问的或者以后永不使用的页面进行淘汰。
(2)举例:假定系统为某进程分配了三块物理块,并有以下页面: 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1 程序运行时,先将7,0,1三个页面装入内存。之后,当进程要访问页面2的时候,将会产生缺页中断。此时根据最佳置换算法,因为页面7要在第18次才能访问,页面0在第5次访问,页面1在第14次访问,页面7最久不被使用,所以将页面7淘汰;当进程0要访问时,因为它已存在在内存所以不必产生缺页中断;当页面3要访问时,又引起缺页中断淘汰1;依次类推直到最后一个页面访问完。下图为采用最佳置换算法的置换图。由图可得,采用最佳置换算法发生了6次缺页中断。
在这里插入图片描述
(3)特点 缺点:最佳置换算法是一种理想化算法,具有较好的性能,但是实际上无法实现(无法预知一个进程中的若干页面哪一个最长时间不被访问);优点:最佳置换算法可以保证获得最低的缺页率
2 先进先出页面置换算法(FIFO)
(1)实现原理:淘汰最先进入内存的页面,即选择在页面待的时间最长的页面淘汰。
(2)举例 依旧是上一个算法的例子 程序运行时,先将7,0,1三个页面装入内存。之后,当进程要访问页面2的时候,将会产生缺页中断。此时根据先进先出置换算法,因为页面7是最先进入内存的,所以将页面7换出;当进程0要访问时,因为它已存在在内存所以不必产生缺页中断;在进程要访问页面3的时候,因为页面0是最早进入内存的,所以将页面0换出;依次类推直到最后一个页面访问完。下图为采用先进先出置换算法的置换图。由图可得,采用最佳置换算法发生了12次缺页中断。先进先出的页面置换比最佳置换算法的页面置换正好多了一倍;
在这里插入图片描述
(3)特点 优点:先进先出算法实现简单,是最直观的一个算法缺点:先进先出的性能最差,因为与通常页面的使用规则不符合,所以实际应用少
3 最近最久未使用置换算法(LRU)
(1)实现原理:选择最近且最久未被使用的页面进行淘汰
(2)举例: 依旧是上一个算法的例子 程序运行时,先将7,0,1三个页面装入内存。之后,当进程要访问页面2的时候,将会产生缺页中断。此时根据最近最久未使用置换算法,因为页面7是最近最久未被使用的的,所以将页面7淘汰;当进程0要访问时,因为它已存在在内存所以不必产生缺页中断;在进程要访问页面3的时候,因为页面1是最近最久未被使用的,所以将页面1淘汰;依次类推直到最后一个页面访问完。下图为采用最近最久未使用的置换算法的置换图。由图可得,采用最近最久未使用置换算法发生了9次缺页中断。
在这里插入图片描述
(3)特点 优点:由于考虑程序访问的时间局部性,一般能有较好的性能;实际应用多缺点:实现需要较多的硬件支持,会增加硬件成本

代码:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define TOTALNUM 320 //要产生的指令的个数
#define MAXAREA 20 //内存中最大能够存放的页面数
int subscript = 0;//表示书数组下标的全局变量
int instruction[TOTALNUM];//储存每次产生的指令编号
int page[TOTALNUM];//存储页面流
int memory[MAXAREA];//内存中页面数组
void replaceArithmatic(int,int);
void insertElement(int,int,int);
void creatInstruction(int,int);
void OPT(int,int,int*);
void FIFO(int,int,int*);
void LRU(int,int,int*);
void replaceArithmatic(int frameNum,int mode){
    int i,j,k;
    int memoryPointer = 0;//为FIFO服务的内存指针
    int full = 0;
    int flag=-1;//当前内存中要交换的下标
    int overflow=0;//溢出
    for(i=0;i<frameNum;i++)//初始化内存
        memory[i]=-1;
    for(i=0;i<TOTALNUM;i++){
        for(j=0;j<frameNum;j++){
            if(memory[j]==-1){
                if(j==frameNum-1)
                    full=1;
                printf("中断!\n");
                memory[j]=page[i];
                overflow++;
                break;
            }
            if(full==1&&memory[j]==page[i]){
                printf("\n\n");
                break;    
            } 
        }
        if(j==frameNum){ //没有命中,需要执行相应的算法
            if(mode==0)
                OPT(i,frameNum,&overflow);
            else if(mode ==1)
                FIFO(i,frameNum,&overflow);
            else if(mode==2)
                LRU(i,frameNum,&overflow);
  
            
        }
        printf("步骤 %3d:  需要页面:%3d 结果:  ",i,page[i]);
        for(j=0;j<frameNum;j++){
            printf("|%2d|   ",memory[j]);
        }
        printf("\n");
    }
    printf("\n命中率为 %f\n",overflow*1.0/TOTALNUM );
}

void creatInstruction(int begin,int end){
    int m0,m1,m2;
    for(;subscript<TOTALNUM-3;){
        m0=(rand()%(end-begin))+begin;
        instruction[subscript]=m0;
        page[subscript]=m0/10;
        subscript++;
        instruction[subscript]=m0+1;
        page[subscript]=(m0+1)/10;
        subscript++;
        m1=rand()%(m0-begin)+begin;
        instruction[subscript]=m1;
        page[subscript]=m1/10;
        subscript++;
        instruction[subscript]=m1+1;
        page[subscript]=(m1+1)/10;
        subscript++;
        m2=rand()%(end-m0)+m0;
        instruction[subscript]=m2;
        page[subscript]=m2/10;
        subscript++;
    }
}



void OPT(int station,int frameNum,int* overflow){
    int j,k;
    int flag=-1;
    printf("\n中断!(OPT)\n");
    for(j=station;j<TOTALNUM;j++){
        for ( k= 0; k<frameNum; k++)
        {
            if(memory[k]==page[j]){
                flag=k;
                break;
            }
        }
    }
    if(flag!=-1)
        memory[flag]=page[station];
    else
        memory[0]=page[station];           
    *overflow+=1;
}
void FIFO(int station,int framNum,int* overflow){
    printf("\n中断!(FIFO)\n");
    int m = *overflow%framNum;
    memory[m]=page[station];
    *overflow+=1;
}

void LRU(int station,int framNum,int* overflow){
    printf("\n中断!(LRU)\n");
    int i,j;
    int flag = -1;
    for(i=station;i>=0;i--){
        for(j=0;j<framNum;j++){
            if(memory[j]==page[i]){
                flag=j;
                break;
            }
        }
    }
    if(flag==-1)
        memory[0]=page[station];
    else
        memory[flag]=page[station];
    *overflow+=1;

}
int main(){
    int i;
    int mode;//选择要执行的算法
    int frameNum=-1;
    srand((unsigned)time(NULL));//随机数播种
    creatInstruction(0,TOTALNUM);
    printf("段数和页数:\n");
    for(i=1;i<=TOTALNUM;i++){
        printf("%3d.段:%4d    页:%3d  |\t",i,instruction[i-1],page[i-1]);
        if(i%3==0)
            printf("\n");
    }
    printf("\n==================================================================================\n");
    printf("*\n");
    printf("选择执行的算法:      (0:OPT\t1:FIFO\t2:LRU\t3:LRF\t-1:退出)\n");
    printf("调用页面:  (1~20)\n*\n");
    printf("==================================================================================\n");
    printf("请输入要调用的页面:\n");
    scanf("%d",&frameNum);
    while(frameNum>20||frameNum<=0){
        printf("输入有误,请重新尝试!\n");
        scanf("%d",&frameNum);
    }
    while(mode!=-1){
        printf("选择要执行的算法:\n");
        scanf("%d",&mode);
        switch (mode)
        {
        case -1:
            printf("退出!\n");
            break;
        case 0:
            printf("============运行OPT============\n");
            replaceArithmatic(frameNum,0);
            break;
        case 1:
            printf("============运行 FIFO===========\n");
            replaceArithmatic(frameNum,1);
            break;
        case 2:
            printf("============运行 LRU============\n");
            replaceArithmatic(frameNum,2);
            break;
        default:
            printf("输入有误!\n");
            break;
        }
    }
}

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

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

  • 3
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OPT算法是一种理论上最优的页面置换算法,其基本思想是在未来的一段时间内不再使用的面应该被置换出去。但是,由于无法准确预测未来的面访问情况,因此实际中无法完全实现OPT算法,只能进行近似。 以下是使用C++模拟页面置换算法实现OPT算法的示例代码: ```c++ #include<iostream> #include<cstring> using namespace std; int main(){ int n, m; //n表示面数,m表示物理块数 cout << "请输入面数和物理块数:"; cin >> n >> m; int pages[n], blocks[m], cnt[m]; //pages存储面序列,blocks存储物理块,cnt存储每个物理块下一次使用的时间 memset(cnt, 0x3f, sizeof(cnt)); //初始化为一个极大值 cout << "请输入面序列:"; for(int i = 0; i < n; i++){ cin >> pages[i]; } int ans = 0; //记录缺次数 for(int i = 0; i < n; i++){ bool flag = false; //标记面是否在物理块中 for(int j = 0; j < m; j++){ if(blocks[j] == pages[i]){ flag = true; break; } } if(flag) continue; //如果在物理块中,直接跳过 int idx = -1, mx = -1; //idx表示需要置换的物理块下标,mx表示该物理块下一次使用的时间 for(int j = 0; j < m; j++){ int k = i + 1; //从下一个面开始找 while(k < n && pages[k] != blocks[j]) k++; if(k == n){ //如果在未来的一段时间内不再使用该面 idx = j; break; } if(k > mx){ //找到下一次使用最晚的面 idx = j; mx = k; } } blocks[idx] = pages[i]; //置换面 cnt[idx] = mx; ans++; //缺次数加1 } cout << "缺次数为:" << ans << endl; return 0; } ``` 在以上代码中,我们首先输入面数和物理块数,然后输入面序列。接着,我们使用两个循环来模拟OPT算法的流程:外层循环遍历面序列,内层循环遍历物理块,查找是否存在该面。如果存在,直接跳过;如果不存在,需要在物理块中选择一个面进行置换。我们使用一个数组cnt来存储每个物理块下一次使用的时间,从而找到需要置换的物理块。最后输出缺次数即可。 需要注意的是,由于OPT算法需要预测未来的面访问情况,因此在实际应用中无法完全实现OPT算法。以上代码只是一种近似实现,可能无法达到最优效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值