操作系统第四次实验 页面置换算法(OPT,FIFO,LRU)

本篇博客介绍了如何通过C语言实现虚拟存储管理中的FIFO、OPT和LRU页面置换算法,通过模拟实验理解算法原理,同时探讨了不同算法在页面置换中的效率和稳定性。通过随机产生的虚页访问序列,展示了页面命中率的计算方法。
摘要由CSDN通过智能技术生成

实验四、虚拟存储管理
一、实验目的:
通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容:
本实验要求使用C语言编程模拟一个拥有若干个虚页的进程在给定的若干个实页中运行、并在缺页中断发生时分别使用FIFO、OPT和LRU算法进行页面置换的情形。
三、实验要求:

  1. 虚页的个数可以事先给定(例如10个),对这些虚页访问的页地址流(其长度可以事先给定,例如20次虚页访问)可以由程序随机产生,也可以事先保存在文件中。
  2. 要求程序运行时屏幕能显示出置换过程中的状态信息并输出访问结束时的页面命中率(命中率=1-页面失效次数/页地址流长度)。
  3. 程序应允许通过为该进程分配不同的实页数,来比较几种置换算法的稳定性。
#include <iostream>
#include <cstring>
using namespace std;

#define num_page 20
#define page_cnt 3

//int page[num_page] = {7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};//页面号引用串
int page[num_page] = {1, 2, 3, 4, 2, 1, 5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6}; //页面号引用串
int res[page_cnt][num_page]; //保存每一次页面置换的结果
int last;     //指向在内存中的页面
int lack;     //缺页次数

//打印结果
void print()
{
    for (int i = 0; i < num_page; i++)
    {
        cout << page[i] << "\t";
    }
    cout << endl;
    for (int i = 0; i < page_cnt; i++)
    {
        for (int j = 0; j < num_page; j++)
        {
            if (res[i][j] != -1)
                cout << "   " << res[i][j] << "\t";
            else
                cout << "    "
                     << "\t";
        }
        cout << endl;
    }
    cout << "缺页次数:" << lack << endl;
    cout << "命中率:" << 1 - ((float)lack / num_page) << endl;
}
//内存初始化
void init()
{
    lack = 0;
    last = 0;
    memset(res, -1, sizeof(int) * num_page * page_cnt);
}
void FIFO()
{
    int cnt = 0;
    int i, j;
    for (i = 0; i < num_page; i++)
    {
        for (j = 0; j < page_cnt; j++)
        {
            if (res[j][last] == page[i])
            {
                break;
            }
        }
        if (j >= page_cnt)
        {
            lack++;
            for (int k = 0; k < page_cnt; k++)
            {
                res[k][i] = res[k][last];
            }
            res[(cnt++) % page_cnt][i] = page[i];
            last = i;
        }
    }
}
//返回最长时间不再访问的页面(所在行号)
int seek(int i)
{
    int a[page_cnt];
    for (int j = 0; j < page_cnt; j++)
    {
        a[j] = num_page;
    }
    bool b[page_cnt] = {false};
    for (int j = i; j < num_page; j++)
    {
        for (int k = 0; k < page_cnt; k++)
        {
            if (!b[k] && res[k][i] == page[j])
            {
                a[k] = j;
                b[k] = true;
            }
        }
    }
    int max = 0;
    for (int j = 1; j < page_cnt; j++)
    {
        if (a[j] > a[max])
        {
            max = j;
        }
    }
    return max;
}
void OPT()
{
    int i, j;
    for (i = 0; i < num_page; i++)
    {
        for (j = 0; j < page_cnt; j++)
        {
            if (res[j][last] == page[i])
            {
                break;
            }
        }
        if (j >= page_cnt)
        {
            lack++;
            for (int k = 0; k < page_cnt; k++)
            {
                res[k][i] = res[k][last];
            }
            res[seek(i)][i] = page[i];
            last = i;
        }
    }
}
//返回最近最久未使用的页面(返回页面所在行号)
int search(int i)
{
    int a[page_cnt];
    memset(a, -1, sizeof(int) * page_cnt);//如果没有搜索到,说明此时还有空闲页面,其值就为-1,返回空闲页面
    bool b[page_cnt] = {false};
    for (int j = i - 1; j >= 0; j--)
    {
        for (int k = 0; k < page_cnt; k++)
        {
            if (!b[k] && res[k][i] == page[j])
            {
                a[k] = j;
                b[k] = true;
            }
        }
    }
    int min = 0;
    for (int j = 1; j < page_cnt; j++)
    {
        if (a[j] < a[min])
        {
            min = j;
        }
    }
    return min;
}
void LRU()
{
    int i, j;
    // bool flag = false;//是否有空闲页面
    // int record;//记录找到的空闲页面
    for (i = 0; i < num_page; i++)
    {
        for (j = 0; j < page_cnt; j++)
        {
            if (res[j][last] == page[i])
            {
                break;
            }
        }
        if (j >= page_cnt)
        {
            lack++;
            for (int k = 0; k < page_cnt; k++)
            {
                res[k][i] = res[k][last];
                // if (res[k][last] == -1 && !flag)
                // {
                //     flag = true;
                //     record = k;
                // }
            }
            res[search(i)][i] = page[i];
            // if (flag)
            // {
            //     res[record][i] = page[i];
            //     flag = false;
            // }
            // else
            // {
            //     res[search(i)][i] = page[i];
            // }
            last = i;
        }
    }
}
int main()
{
    cout << "FIFO算法" << endl;
    init();
    FIFO();
    print();
    cout << "OPT" << endl;
    init();
    OPT();
    print();
    cout << "LRU算法" << endl;
    init();
    LRU();
    print();
    return 0;
}

结果
在这里插入图片描述

一、实验名称 模拟操作系统的页面置换 二、实验目的 1、掌握操作系统的页面置换过程,加深理解页式虚拟存储器的实现原理。 2、掌握用随机数生成满足一定条件的指令地址流的方法。 3、掌握页面置换的模拟方法。 三、实验要求与提示 1、 采用一种熟悉的语言,如C、PASCAL或C++等,编制程序。 2、 模拟操作系统采用OPTFIFOLRU算法进行页面置换的过程。 3、 设程序地址范围为0到32767,采用随机数生成256个指令地址,满足50%的地址是顺序执行,25%向前跳,25%向后跳。为满足上述条件,可采取下列方法:设d0=10000,第n个指令地址为dn,第n+1个指令地址为dn+1,n的取值范围为0到255。每次生成一个1到1024范围内的随机数a,如果a落在1到512范围内,则dn+1=dn+1。如果a落在513到768范围内,则设置dn+1为1到dn范围内一个随机数。如果a落在769到1024范围内,则设置dn+1为dn到32767范围内一个随机数。 4、 页面大小的取值范围为1K,2K,4K,8K,16K。按照页面大小将指令地址转化为页号。对于相邻相同的页号,合并为一个。 5、 分配给程序的内存块数取值范围为1块,2块,直到程序的页面数。 6、 分别采用OPTFIFOLRU算法对页号序列进行调度,计算出对应的缺页断率。 7、 打印出页面大小、分配给程序的内存块数、算法名、对应的缺页断率。 8、 分析页面大小和分配给程序的内存块数对缺页断率的影响。分析不同的页面置换算法的调度性能。 9、 在上机实现该程序之后,要求写出实验报告,其包括实验名称、实验目的、实验内容、程序的主要流程图、实验心得和主要源程序清单等。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值