一、实验目的

1、通过软件模拟页面置换过程,加深对请求页式存储管理实现原理的理解

2、理解和掌握OPT、FIFO和LRU三种页面置换算法,深入分析三者之间的优缺点。

二、实验环境

硬件环境:计算机一台,局域网环境;

软件环境: Windows或Linux操作系统, C语言编程环境。

三、实验内容和步骤

参考设计思路

(1)重要数据结构

① 页表数据结构

typedef struct

{

int vmn;

int pmn;

int exist;

int time;

}vpage_item;

vpage_item page_table[VM_PAGE];

页表是虚地址向物理地址转换的依据,包含虚页号所对应的实页号,是否在物理内存中。

页表中增加了一个time项,用于替换算法选择淘汰页面,在不同的替换算法中,time含义不一样。

在LRU算法中,time为最近访问的时间。该虚页每访问一次,time置为当前访问时刻,淘汰页面时,淘汰time值最小的,即最久没有被使用的。

在FIFO算法中,time为该虚页进入内存的时间。只有当该虚页从外存进入内存时,才置该标志。淘汰页面时,淘汰time值最小的,即最早进入内存的虚页。

在OPT算法中,time没有任何意义。

② 物理页位图数据结构

vpage_item * ppage_bitmap[PM_PAGE];

物理页位图是用于记录物理页是否被使用,用于物理页内存的分配。正常情况下是一个数组,元素值为0时,代表相应物理页没有装入任何虚页,值为1时,代表该物理页装入虚页。但为方便替换算法检索要替换出去的虚页,数组的每个元素值为当前放在该物理页的页表项的指针。若值为NULL,则表示该物理页没有被占用,当值不为NULL时,表示正在占用该物理页的虚页。

③指令相关数据结构

//每条指令信息

typedef struct{

int  num;

int  vpage;

int  offset;

int  inflow;

}instr_item;

//指令数组

instr_item instr_array[TOTAL_INSTR];

//指令流数据结构

struct instr_flow{

instr_item *instr;

struct instr_flow *next;

};

//指令流头数据结构

struct instr_flow_head{

int num;

struct instr_flow *next;

};

struct instr_flow_head iflow_head;

每条指令包括指令号、该指令所属虚页及页内偏移(这两项可以根据指令号计算出来,增加这两项是为了方便编程)。inflow是一个辅助项,用于构建指令流。

本题要求,按照规则生成的指令流中,应包含所有的共320条指令。但每次随机生成的指令号,可能已在指令流中,因此最终指令流中的指令数可能远远超过320条指令。

设置inflow的目的是为了便于统计是否320条指令均已加入到指令流中。在该条指令加入到指令流中时,如果inflow为0,表示该指令尚未在指令流中,则统计数加1;如果inflow为1,表示该指令已经加入过指令流,该指令虽然再次加入指令流,但统计数不增加。这样,当统计计数为320时,表示所有的指令均已加入到指令流中。

struct instr_flow为指令流数据结构,struct instr_flow_head始终指向指令流的头,其中num用于指令流中指令数量计数,用于计算缺页率。

(2)主程序,如下图所示。

(3)指令流生成流程

指令流的生成按照实验要求生成,其算法流程如下图所示。


(4)物理内存分配流程

物理内存分配时,需要根据当前置换算法选择淘汰页面。其算法流程下图所示。

(5)运行流程图,如下图所示。

(6)三种置换算法

①OPT算法:在当前指令的后续指令流中,寻找已在内存中的虚页,哪个最远才被使用,反过来,如果先找到最近三个(物理页面总数为4)也在内存中的虚页,则剩下的那个虚页肯定就是最远才被使用的虚页,该虚页被淘汰,其物理内存分配给当前指令所在的虚页。

②FIFO算法:在已在物理内存中的虚页中,寻找time最小的虚页(最早进入物理内存的虚页),该虚页即是被淘汰的虚页。

③LRU算法:思想同FIFO算法,但time最小的虚页含义是最久没有被使用的虚页。

在这三种置换算法中,OPT的算法稍微复杂一些,下图给了该算法的程序流程图。

程序代码

#include <iostream>
#define VM_PAGE 32      /*假设每个页面可以存放10条指令,则共有32个虚页*/
#define PM_PAGE 4       /*分配给作业的内存块数为4*/
#define TOTAL_INSTR 320 /*320条指令*/
using namespace std;
int instr_count = 0;
typedef struct
{int vmn; //虚页号int pmn;//实页号int exist;//是否存在内存int time;//时间,作为置换依据
}vpage_item;
vpage_item page_table[VM_PAGE];//虚页表
vpage_item* ppage_bitmap[PM_PAGE]; //实页表//每条指令信息
typedef struct {int  num;//指令号int  vpage;//虚页号int  offset;//页内偏移int  inflow;//是否在指令流中
}instr_item;//指令数组
instr_item instr_array[TOTAL_INSTR];//指令流数据结构
struct instr_flow {instr_item* instr;struct instr_flow* next;
};
//指令流头数据结构
struct instr_flow_head {int num = 0;//用于指令流中指令数量计数struct instr_flow* next;
};
struct instr_flow_head iflow_head;void Init_PTable() //页表初始化
{for (int i = 0; i < VM_PAGE; i++){page_table[i].vmn = i + 1;  //虚页号page_table[i].pmn = -1;    //实页号page_table[i].exist = 0;page_table[i].time = -1;}for (int i = 0; i < PM_PAGE; i++){ppage_bitmap[i] = NULL;}
}void Init_Instr()
{int n, count = 1, i = 0,m;for (i = 0; i < TOTAL_INSTR; i++){instr_array[i].num = i;if (count % 10 != 0)m = count / 10 + 1;elsem = count / 10;instr_array[i].vpage = m;instr_array[i].offset = count - (m - 1) * 10 - 1;instr_array[i].inflow = 0;count++;}srand((unsigned)time(NULL));instr_flow* p_instr_flow = new instr_flow;iflow_head.next = p_instr_flow;while(true){n = rand() % TOTAL_INSTR;if (instr_array[n].inflow == 0) {instr_array[n].inflow = 1;iflow_head.num++;}instr_count++;p_instr_flow->instr = new instr_item;p_instr_flow->instr = instr_array + n;p_instr_flow->next = new instr_flow;printf("%d\t%d\t%d\n", p_instr_flow->instr->num, p_instr_flow->instr->vpage, p_instr_flow->instr->offset);if (iflow_head.num == TOTAL_INSTR) {//所有指令均位于指令流中p_instr_flow->next = NULL;break;             }p_instr_flow = p_instr_flow->next;}
}
void FIFO()/*FIFO页面置换算法*/
{int k = 0;int i;int missing_page_count = 0;int current_time = 0;instr_flow* p_instr_flow = new instr_flow;p_instr_flow = iflow_head.next;while (p_instr_flow!=NULL){if (page_table[p_instr_flow->instr->vpage - 1].exist == 0){missing_page_count++;if (k < PM_PAGE){if (ppage_bitmap[k] == NULL) /*找到一个空闲物理块*/{ppage_bitmap[k] = &page_table[p_instr_flow->instr->vpage - 1];ppage_bitmap[k]->exist = 1;ppage_bitmap[k]->pmn = k;ppage_bitmap[k]->time = current_time;k++;}}else{int temp = ppage_bitmap[0]->time;  /*记录物理块中作业最早到达时间*/int j = 0;                    /*记录应当被替换的物理块号*/for (i = 0; i < PM_PAGE; i++)   /*寻找最早到达的作业*/{if (ppage_bitmap[i]->time < temp){temp = ppage_bitmap[i]->time;j = i;}}ppage_bitmap[j]->exist = 0;ppage_bitmap[j] = &page_table[p_instr_flow->instr->vpage - 1];      /*更新页表项*/ppage_bitmap[j]->exist = 1;ppage_bitmap[j]->pmn = j;ppage_bitmap[j]->time = current_time;}}current_time++;p_instr_flow = p_instr_flow->next;}printf("FIFO算法缺页次数为:%d\t缺页率为:%f\t置换次数为:%d\t置换率为:%f\n", missing_page_count, missing_page_count / (float)instr_count, missing_page_count - 4, (missing_page_count - 4) / (float)instr_count);
}
void LRU()
{int k = 0;int i;int missing_page_count = 0;int current_time = 0;instr_flow* p_instr_flow = new instr_flow;//bool isleft = true;   /*当前物理块中是否有剩余*/p_instr_flow = iflow_head.next;while (p_instr_flow != NULL){if (page_table[p_instr_flow->instr->vpage - 1].exist == 0)/*当前指令不存在物理块中*/{missing_page_count++;if (k < PM_PAGE){if (ppage_bitmap[k] == NULL) /*找到一个空闲物理块*/{ppage_bitmap[k] = &page_table[p_instr_flow->instr->vpage - 1];ppage_bitmap[k]->exist = 1;ppage_bitmap[k]->pmn = k;ppage_bitmap[k]->time = current_time;k++;}}else{int temp = ppage_bitmap[0]->time; /*记录物理块中作业最早到达时间*/int j = 0;                    /*记录应当被替换的物理块号*/for (i = 0; i < PM_PAGE; i++)/*找到时间最小的物理块,也就是最久未使用的*/{if (ppage_bitmap[i]->time < temp){temp = ppage_bitmap[i]->time;j = i;}}ppage_bitmap[j]->exist = 0;ppage_bitmap[j] = &page_table[p_instr_flow->instr->vpage - 1];      /*更新页表项*/ppage_bitmap[j]->exist = 1;ppage_bitmap[j]->pmn = j;ppage_bitmap[j]->time = current_time;}}else/*当前指令在物理块中,时间更新*/{page_table[p_instr_flow->instr->vpage - 1].time = current_time;}current_time++;p_instr_flow = p_instr_flow->next;}printf("LRU算法缺页次数为:%d\t缺页率为:%f\t置换次数为:%d\t置换率为:%f\n", missing_page_count, missing_page_count / (float)instr_count, missing_page_count - 4, (missing_page_count - 4) / (float)instr_count);
}void OPT()
{int k = 0;int missing_page_count = 0;int current_time = 0;instr_flow* p_instr_flow = new instr_flow;p_instr_flow = iflow_head.next;while (p_instr_flow != NULL) {if (page_table[p_instr_flow->instr->vpage - 1].exist == 0) {missing_page_count++;if (k < PM_PAGE){if (ppage_bitmap[k] == NULL) /*找到一个空闲物理块*/{ppage_bitmap[k] = &page_table[p_instr_flow->instr->vpage - 1];ppage_bitmap[k]->exist = 1;ppage_bitmap[k]->pmn = k;ppage_bitmap[k]->time = current_time;k++;}}else {int used[VM_PAGE] = { 0 };/*记录哪些虚页已经使用*/int i;instr_flow* pp_instr_flow = p_instr_flow->next;int count = 0;/*便利剩余指令*/for (pp_instr_flow; pp_instr_flow != NULL; pp_instr_flow = pp_instr_flow->next) {if (page_table[pp_instr_flow->instr->vpage - 1].exist == 1) {used[page_table[pp_instr_flow->instr->vpage  - 1].vmn - 1] = 1;}for (i = 0; i < VM_PAGE; i++) {if (used[i] == 1) {count++;}}if (count == 3) {break;}}for (i = 0; i < PM_PAGE; i++) {if (used[ppage_bitmap[i]->vmn - 1] == 0) {ppage_bitmap[i]->exist = 0;ppage_bitmap[i] = &page_table[p_instr_flow->instr->vpage - 1];ppage_bitmap[i]->exist = 1;ppage_bitmap[i]->pmn = i;ppage_bitmap[i]->time = current_time;}}}}current_time++;p_instr_flow = p_instr_flow->next;}printf("OPT算法缺页次数为:%d\t缺页率为:%f\t置换次数为:%d\t置换率为:%f", missing_page_count, missing_page_count / (float)instr_count, missing_page_count - 4, (missing_page_count - 4) / (float)instr_count);
}
int main()
{Init_PTable();cout << "指令流如下:" << endl;printf("-----------------------------------------------\n");printf("指令号\t所在页\t页内位移\n");printf("-----------------------------------------------\n");Init_Instr();printf("-----------------------------------------------\n");cout << "共计" << instr_count << "条指令" << endl;cout << endl << endl;FIFO();Init_PTable();LRU();Init_PTable();OPT();return 0;}

实验结果

实验分析

①分析实验结果产生的原因,总结从实验观察到的结果,分析三种置换算法的缺页率的差异。

FIFO算法每次先替换最先进入的页面,LRU算法每次先替换最近最久未使用的页面,OPT算法每次先替换将来最长时间内不再被访问的页面。所以FIFO算法的置换率相对较大,而LRU算法考虑到了程序的局部性原理,相对较小,OPT算法也相对较小。

②结合操作系统课程中讲授的原理,写出本次实验的心得体会。

FIFO算法置换最先调入内存的页面,即置换在内存中驻留时间最久的页面。按照进入内存的先后次序排列成队列,从队尾进入,从队首删除。但是该算法会淘汰经常访问的页面,不适应进程实际运行的规律。

LRU算法置换最近一段时间以来最长时间未访问过的页面。根据程序局部性原理,刚被访问的页面,可能马上又要被访问;而较长时间内没有被访问的页面,可能最近不会被访问。普偏地适用于各种类型的程序,但是系统要时时刻刻对各页的访问历史情况加以记录和更新,开销太大,因此LRU算法必须要有硬件的支持。

OPT算法置换以后不再被访问,或者在将来最迟才回被访问的页面,缺页中断率最低。但是该算法需要依据以后各业的使用情况。所以OPT算法不可能实现。

实验八 页面置换模拟程序设计相关推荐

  1. 页面置换模拟程序设计

    页面置换模拟程序设计 1.通过软件模拟页面置换过程,加深对请求页式存储管理实现原理的理解 2.理解和掌握OPT.FIFO和LRU三种页面置换算法,深入分析三者之间的优缺点. #include<s ...

  2. 操作系统实验八:页面置换模拟程序设计

    一.实验目的 1.通过软件模拟页面置换过程,加深对请求页式存储管理实现原理的理解 2.理解和掌握OPT.FIFO和LRU三种页面置换算法,深入分析三者之间的优缺点. 二.实验环境 硬件环境:计算机一台 ...

  3. 操作系统实验:页面置换算法的模拟实现及命中率对比(学习笔记)

    操作系统实验:页面置换算法的模拟实现及命中率对比(学习笔记) 题目要求 输入要求 输出要求 编程平台 实验成果 开始模拟 错误输入 退出程序 代码实现 抽象数据类型定义 指令地址流生成 指令地址流到页 ...

  4. 操作系统实验2—页面置换算法模拟程序设计

    一.实验目的 对页面置换做进一步的理解. 了解页面置换的任务. 通过编程掌握页面置换算法及缺页率计算. 了解Belady现象和抖动现象. 二.实验内容 输入给出一组页面访问顺序(如页面走向是1.2.5 ...

  5. 【南邮操作系统实验】页面置换算法(FIFO、LRU、OPT)图形化界面(JavaFx)

    页面置换算法图形化界面 前言 运行效果 源码 FIFO LRU OPT FXML界面 控制器 启动类 前言 其实以前操作系统实验的时候我写过了三份了:(命令行) 页面置换算法 (FIFO.LRU.OP ...

  6. android内存置换,课内资源 - 基于Android实现的页面置换模拟

    一.使用说明 1.1 项目简介 请求分页分配方式的模拟,包括页面.页表.地址的转换和页面置换过程,并通过该模拟过程加深对请求调页系统的原理和实现过程的理解.并且学习Android环境下使用Java编写 ...

  7. 【南邮操作系统实验】页面置换算法 (FIFO、LRU、OPT)Java 版

    页面置换算法Java版 先进先出置换算法(FIFO) 最近最久未使用置换算法(LRU) 最佳置换算法(OPT) 帮女朋友写了份 Python版的,Python版戳这里 帮女朋友舍友写了份 C++ 版的 ...

  8. 【南邮操作系统实验】页面置换算法(FIFO、LRU、OPT) C++ 版

    页面置换算法 先进先出置换算法(FIFO) 最近最久未使用置换算法(LRU) 最佳置换算法(OPT) 写好了 Java 版和 Python 版的- Java版这里 Python版戳这里 帮女朋友舍友写 ...

  9. 【南邮操作系统实验】页面置换算法(FIFO、LRU、OPT) Python 版

    页面置换算法 先进先出置换算法(FIFO) 最近最久未使用置换算法(LRU) 最佳置换算法(OPT) 本来已经写好一份 Java 版的了,然后又帮女朋友写了一份 Python 版,啊哈哈 Java版戳 ...

最新文章

  1. mysql利用CPU多核
  2. PyQt5教程——组件 Ⅱ(八)
  3. 【蓝桥杯Java_C组·从零开始卷】第八节、综合测试
  4. 临沂大学3加4计算机专业,临沂大学2021年电子信息(计算机技术方向) 硕士研究生调剂工作细则...
  5. ubuntu 开启 rewrite 模块
  6. 微软再向开发者重申:UWP 是 PC 的最佳平台
  7. wamp下更改mysql密码
  8. logging日志模块
  9. java注解_Java注解
  10. python数据分析numpy_Python数据分析之numpy学习(一)
  11. 机器学习 结构化数据_聊天机器人:根据结构化数据创建自然语言
  12. 打印机质量测试软件,打印质量测试
  13. C++Windows连点器制作
  14. 飞信2009_从飞信倒下的八个原因看运营商的复兴之路
  15. 什么是表压?什么是绝压?表压和绝压什么关系?
  16. 为小米4与小米3 Mi3 Mi4编译Cyanogenmod 12.1与13.0 (CM12与CM13) 的步骤以及错误解决
  17. 导数卷积 牛客 NTT
  18. tftp64能Ping通,但是无法load下载bin文件
  19. 【ubuntu拷贝目录】cp: omitting directory”错误的解释和解决办法
  20. “耳根”发布新作《一念永恒》,交易记录

热门文章

  1. 谷歌黑搜索怎么收_谷歌搜索持久的反黑种族主义
  2. python获取鼠标的当前坐标
  3. 用于Transformer的6种注意力的数学原理和代码实现
  4. Unity3d数字地球谷歌地球文章合集
  5. 【协议分析】Gzip格式与解析
  6. AD采集中常用的Ksps什么意思
  7. CodeForces 427C Checkposts (强连通分量Tarjan模板题)
  8. <<和>>运算符的用法
  9. c v开发语言,被质疑的 V 语言
  10. oracle 毫秒时间换mysql_Mysql与Oracle常用时间格式的转换