操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

这篇具有很好参考价值的文章主要介绍了操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

文章目录

一、概述

 (1)置换算法

 (2)缺页率与命中率

二、先进先出置换算法(FIFO)

   (1)定义

   (2)示例

 (3)Belady异常

 三、最近最久未使用置换算法(LRU)

(1)定义

(2)示例

四、FIFO&LRU置换算法的模拟

   (1)流程图

 (2)完整代码

 (3)实验结果


一、概述

(1)置换算法

        进程运行时,若其访问的页面不在内存中而需要将其调入,但内存已经无空闲空间时,就需要从内存中调出一页程序或者数据,送入磁盘的对换区。

        选择调出页面的算法就称为页面置换算法。常见的页面置换算法有以下四种:

  • 最佳置换算法(OPT)
  • 先进先出页面置换算法(FIFO)
  • 最近最久未使用置换算法(LRU)
  • 时钟置换算法(CLOCL)

(2)缺页率与命中率

        当前访问的页面不在内存中时,此时发生缺页中断,选择合适的页面置换算法来从内存中调出一页程序或者数据,送入磁盘的对换区,与当前要访问的页面进行置换,从而满足当前的访问需求。这种情况就叫缺页,相反,如果当前访问的页面在内存中时,即为命中。二者有如下关系:

  • 缺页率+命中率=1
  • 缺页率=缺页次数/总页面访问次数
  • 命中率=命中次数/总页面访问次数

本次实验重点是模拟先进先出和最近最久未使用算法的执行过程。


二、先进先出置换算法(FIFO)

(1)定义

        优先淘汰那些最早进入内存的页面,即淘汰在内存中驻留时间最久的页面。该算法实现简单,只需把已调入内存的页面根据先后次序链接成队列,设置一个指针总是指向最老的页面。

(2)示例

假定系统为某个进程分配了3个物理块,访问页面依次如下:7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1

操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

按照FIFO算法, 当依次访问页面7,0,1时,由于都不在内存中发生缺页中断,因为有3个物理块且内存空闲,所以可以不用置换页面直接将这三个页面依次放入内存中;当访问页面2时,由于不在内存中,发生缺页中断,此时按照FIFO置换算法将内存中最早进入内存的页面7与2置换,让2进入内存,后面以此类推。

(3)Belady异常

        分配给进程的物理块增多,但是缺页率却不减反增的现象被称之为Belady异常。如图:

操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

 当进程有3个物理块时,缺页次数为9,缺页率为75%

 当进程有4个物理块时,缺页次数为10,缺页率为83.33%

 另外,只有FIFO算法会出现Belady异常,其它算法不会出现这种情况!


 三、最近最久未使用置换算法(LRU)

(1)定义

        选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。该算法为每个页面设置一个访问字段,用来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。

(2)示例

        再对上面的例子采用LRU算法进行页面置换,如图3.25所示。进程第一次对页面 2访问时,将最近最久未被访问的页面7置换出去。然后在访问页面3时,将最近最久未使用的页面1换出。

操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

        LRU算法的性能较好,但需要寄存器和栈的硬件支持。LRU是堆栈类的算法。理论上可以证明,堆栈类算法不可能出现Belady异常。FIFO 算法基于队列实现,不是堆栈类算法。


四、FIFO&LRU置换算法的模拟

(1)流程图

操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

 (2)完整代码

/*
虚拟存储器之页面置换算法的模拟 
测试数据1:20个访问的页面  3个物理块:
7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
测试数据2:10个访问页面  2个物理块
4 2 3 0 3 2 1 2 0 1
*/
#include <stdio.h>
#define phy 100
#define page 100//页面最大数
#define phyBlock 100//物理块最大数
int phyBlockNum;//物理块的数量
int pageNum;//页面数量
int pageNumStrList[page];//保存页面号引用串
//初始化队列
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|\t", list[i]); 
    }
    printf("\n");
}
//页面置换结果分析统计 
void informationCount(int missingCount, int replaceCount, int pageNum)
{
    printf("---------------------------结果分析--------------------------\n");
    printf("缺页次数:%d\n", missingCount);
    double a=(double)missingCount/pageNum;//计算缺页率以百分号形式表示 
    printf("缺页率:%.2f%%\n", a*100);
    double result = (double)(pageNum - missingCount) / (double)pageNum;
    printf("置换次数:%d\n", replaceCount);
    printf("------------------------------------------------------------\n");
}
//寻找该页面下次要访问的位置
int getNextPosition(int currentPage, int currentPosition, int strList[], int pageNum)
{
    for (int i = currentPosition + 1; i < pageNum; i++)
    {
        if (strList[i] == currentPage)
        {
            return i;
        }
    }
    return 100;
}
//FIFO:先进先出置换算法
void replacePageByFIFO(int memoryList[], int phyNum, int strList[], int pageNum) {
    int replaceCount = 0; //置换次数
    int missingCount = 0; //缺页次数
    int pointer = 0; //记录当前最早进入内存的下标
    int isVisited = 0;//记录当前页面的访问情况: 0表示未访问,1表示已访问 
    for (int i = 0; i < pageNum; i++) {
        isVisited = 0;
        //判断是否需要置换,内存已满且需要访问的页面不在内存中
        for (int j = 0; j < phyNum; j++) {
            if (memoryList[j] == strList[i]) {
                //1.该页面已经存在内存中
                //修改访问情况
                isVisited = 1;
                //修改访问时间
                printf("%d\t", strList[i]);
                printf("\n");
                break;
            }
            if (memoryList[j] == -1) {
                //2.页面不在内存中且内存未满则直接存入即可 
                memoryList[j] = strList[i];
                //修改访问情况
                isVisited = 1;
                missingCount++;
                printf("%d\t", strList[i]);
                showMemoryList(memoryList, phyNum);
                break;
            }
        }
        //当前页面还未被访问过,需要进行页面置换
        if (!isVisited) {
            //直接把这个页面存到所记录的下标中
            memoryList[pointer] = strList[i];
            pointer++; //下标指向下一个
            //如果到了最后一个,将下标归零
            if (pointer > phyNum - 1) {
                pointer = 0;
            }
            missingCount++;
            replaceCount++;
            printf("%d\t", strList[i]);
            showMemoryList(memoryList, phyNum);
        }
    }
    informationCount(missingCount, replaceCount, pageNum);
}

//LRU:最近最久未使用置换算法
void replacePageByLRU(int memoryList[], int phyNum, int strList[], int pageNum) {
    int replaceCount = 0;//置换次数
    int missingCount = 0;    //缺页次数
    int timeRecord[phy]; //记录内存中最近一次访问至今的时间
    initializeList(timeRecord, phyNum);
    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] != -1) {
                timeRecord[j] ++;
            }
            if (memoryList[j] == strList[i]) {
                //该页面已经存在内存中
                //修改访问情况
                isVisited = 1;
                //重置访问时间
                timeRecord[j] = -1;
                printf("%d\t", strList[i]);
                printf("\n");
                break;
            }
            if (memoryList[j] == -1) {
                //页面不在内存中且内存未满,直接存入
                memoryList[j] = strList[i];
                pageCount++;
                //修改访问情况
                isVisited = 1;
                //修改访问时间
                timeRecord[j]++;
                missingCount++;
                printf("%d\t", 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\t", strList[i]);
            showMemoryList(memoryList, phyNum);
        }
    }
    informationCount(missingCount, replaceCount, pageNum);
}
//测试 
int main(int argc, const char* argv[])
{
	printf("------------------虚拟存储器之页面置换算法------------------\n"); 
    printf("请输入内存的物理块数量:");
    scanf("%d", &phyBlockNum);
    //生成内存队列
    int memoryList[phyBlock];
    //初始化内存状态
    initializeList(memoryList, phyBlockNum);
    //showMemoryList(memoryList,phyBlockNum);
    printf("请输入要访问的页面总数:");
    scanf("%d", &pageNum);
    printf("请输入要访问的页面号:");
    for (int i = 0; i < pageNum; i++) {
        scanf("%d", &pageNumStrList[i]);
    }
    printf("------------------------------------------------------------\n");
    int chose;
    while (1)
    {
        printf("★请选择你要执行的操作:(1.FIFO算法 2.LRU算法 3.退出):");
        scanf("%d", &chose);
        switch (chose)
        {
        case 1:
        	printf("------------------------------------------------------------\n");
        	printf("页面号\t");
        	for(int i=0;i<phyBlockNum;i++){
        		printf("物理块%d\t",i+1);
        	}
        	printf("\n");
            replacePageByFIFO(memoryList, phyBlockNum, pageNumStrList, pageNum);
            //重新初始化内存
            initializeList(memoryList, phyBlockNum);
            break;
        case 2:
        	printf("------------------------------------------------------------\n");
            printf("页面号\t");
        	for(int i=0;i<phyBlockNum;i++){
        		printf("物理块%d\t",i+1);
        	}
        	printf("\n");
            replacePageByLRU(memoryList, phyBlockNum, pageNumStrList, pageNum);
            //重新初始化内存
            initializeList(memoryList, phyBlockNum);
            break;
        default:
        	printf("退出成功");
            return 0;
            break;
        }
    }
    return 0;
}

(3)实验结果

操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)

最后, 如果本文内容对你有所帮助,记得点赞收藏哈。文章来源地址https://www.toymoban.com/news/detail-445299.html

到了这里,关于操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFO&LRU)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【操作系统复习之路】存储器管理(第四章 &超详细讲解)

    【操作系统复习之路】存储器管理(第四章 &超详细讲解)

    目录 一、存储器的层次结构 二、程序的装入和链接 2.1 逻辑地址和物理地址 2.2 绝对装入方式 2.3 可重定位装入方式 2.4 动态运行时装入方式 2.5 静态链接  2.6 装入时动态链接 2.7 运行时动态链接 三、连续分配存储器管理方式 3.1 单一连续分配 3.2 固定分区分配 3.3 动态分区

    2024年04月27日
    浏览(7)
  • 操作系统考试复习——第四章 存储器管理 4.1 4.2

    操作系统考试复习——第四章 存储器管理 4.1 4.2

    存储器的层次结构: 存储器的多层结构: 存储器至少分为三级:CPU寄存器,主存和辅存。 但是 一般分为6层 为寄存器,高速缓存,主存储器,磁盘缓存,固定磁盘,可移动存储介质。 这几个部分是 速度依次减小 但是 存储容量是依次增大 的。  只有固定磁盘和可移动存储

    2024年02月03日
    浏览(9)
  • 实验二 存储器实验

    实验二 存储器实验

    一、FPGA 中 LPM_ROM 定制与读出实验的实验步骤 第一步:创建新的工程建立mif文件 File---New Project wizard.... ---选择芯片cyclone IV EP4CE22F17C8---建立存储器初始化文件ROM1.mif  ---创建一个128*32bits空间大小的存储空间---输入初始化数据(如图5.1ROM1的数据) 图5.1 ROM1的数据 第二步:调用

    2024年02月03日
    浏览(10)
  • quartus存储器实验

    quartus存储器实验

    实验目的 1、掌握FPGA中lpm_ROM只读存储器配置方法。 2、用文本编辑器编辑mif文件配置ROM,加载于ROM中; 3、验证FPGA中mega_lpm_ROM的功能   设置硬件。不设置不影响仿真。 新建好了一个空的工程。 注意:电路图文件名和顶层名字要一样。 开始画图,双击空白地方。    点击ok,

    2024年02月05日
    浏览(12)
  • 静态存储器扩展实验

    静态存储器扩展实验

    一、实验目的:    按照规则字写存储器,编写实验程序,将N个数写入SRAM的某段空间中,查看该存储空间,检测写入是否正确。 二、实验内容与要求:       按照规则字写存储器,编写实验程序,将0000H~000FH 共16个数写入SRAM的从0000H起始的一段空间中,然后通过系统命令查

    2023年04月09日
    浏览(7)
  • 虚拟存储器

    虚拟存储器

    虚拟存储器是 主存-辅存 层次的,虚拟存储器主要是由操作系统实现,在计算机组成原理中应更加关注主存-Cache 1、实地址(物理地址):计算机物理内存的访问地址。 2、虚地址(逻辑地址):用户编程时使用的地址。 3、再定位:程序进行虚地址到实地址转换的过程。 4、

    2024年02月05日
    浏览(4)
  • 西电计组实验一 存储器实验

    西电计组实验一 存储器实验

    一.实验目的   1.掌握FPGA中lpm_ROM的设置,作为只读存储器ROM的工作特性和配置方法;   2.用文本编辑器编辑mif文件配置ROM,学习将程序代码以mif格式文件加载于lpm_ROM中;   3.在初始化存储器编辑窗口编辑mif文件配置ROM;   4.验证FPGA中mega_lpm_ROM的功能。 二.实验原

    2024年02月04日
    浏览(9)
  • 计算机组成原理实验 实验一 存储器实验

    计算机组成原理实验 实验一 存储器实验

    目录 实验1  存储器实验 一、实验目的 二、实验原理 三、实验电路 四、实验步骤 五、实验数据分析 六、思考题 1.熟悉DVCC计算机组成原理实验机的结构,掌握其主要操作。 2.掌握静态随机存储器RAM工作特性。 3.掌握静态随机存储器RAM的数据读写方法。 4.能够运用静态随机存

    2023年04月18日
    浏览(8)
  • 计算机组成原理实验——三、存储器实验

    计算机组成原理实验——三、存储器实验

    1.掌握存储器的工作原理和接口。 2.掌握存储器的实现方法和初始化方法。 3.掌握RISC-V中存储器的存取方式。 1.利用vivado IP核创建64 32的ROM,并在 系数文件中设置数据为123489ab; 2.利用vivado IP核创建64 32的RAM,并在 其上封装一个模块,使得其能完成risc-v 的load/store指令功能。

    2024年02月04日
    浏览(9)
  • 计算机组成原理 存储器实验

    计算机组成原理 存储器实验

    计算机组成原理实验环境 掌握静态随机存储器 RAM 的工作特性。 掌握静态随机存储器 RAM 的读写方法。 做好实验预习,熟悉 MEMORY6116 芯片各引脚的元器件的功能和连接方式,熟悉其他实验元器件的功能特性和使用方法,看懂电路图。 按照实验内容与步骤的要求,认真仔细地

    2024年02月02日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包