操作系统实验报告
实验五:请求页式存储管理的模拟
一、实验内容
熟悉虚拟存管理的各种页面置换算法,并编写模拟程序实现请求页式存储管理的页面置换算法----FIFO,测试分配不同数目物理页面时的缺页率,并绘制“物理页面/缺页率”曲线图,圈出工作点(Operating point)。
二、实验要求
- 1、理解固定物理页面情况下,FIFO页面置换算法, 分析算法的执行过程。页面访问序列是随机的,具有足够的长度(大于35个);序列中每个地址是随机的、每项元素有重复的(随机数取值最好的0~9之间)。
- 2、每次置换时,要求显示分配状态(每个页框里装载的具体内容)和缺页率。贴其中一个运行结果图。
- 3、记录同样的页面访问序列(使用同一组访问序列数据的情况下),在不同物理页框下(改变页框数)的缺页情况,查看缺页率的变化,记录到Excel表里。
- 4、用Excel绘制“物理页面/缺页率” 曲线图,圈出操作点(拐点)。
三、FIFO页面置换算法
3.1 算法描述
总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。
3.2 页面的数据结构说明
struct PageInfo{
int serial[50]; // 模拟的最大访问页面数,实际控制在30以上
int diseffect; // 缺页次数
int total_pf; // 分配的页框数
int total_pn; // 访问页面序列长度
} pf_info;
3.3 算法实现的流程
图1 算法实现流程图
四、代码实现
#include <iostream>
#include <random>
#include <synchapi.h>
#include <fstream>
#include <iomanip>
using namespace std;
//全局变量
int PAGEFRAMENUM; //物理页面数目,假定刚开始先固定物理块为6
int vpoint; //页面访问指针
int pageframe[1000]; // 分配的页框,将来可随时改变分配的页框数
int rpoint; //页面替换指针
//页面信息结构
struct PageInfo {
int serial[50]; // 模拟的最大访问页面数,实际控制在30以上
int diseffect; // 缺页次数
int total_pf; // 分配的页框数
int total_pn; // 访问页面序列长度
} pf_info;
void createps(); // 随机页面序列进程
void displayinfo(int pstate); // 展示所创建的序列
void FIFO(); // FIFO页面置换算法
int findpage(); //查找页面是否在内存,1为在内存,0为不在即缺页
// 随机页面序列进程
void createps(){
// 随机产生页面序列长度30~50
pf_info.total_pn = ((float)rand() / 32767) * 21 + 35;
// 随机访问的每个序列值0~9
for(int i = 0; i < pf_info.total_pn; i++){
pf_info.serial[i] = ((float)rand() / 32767) * 10;
}
}
// 展示所创建的序列(每访问一个页面,打印一行信息(该页是否缺页))
void displayinfo(int pstate) {
printf("ID:%2d 访问%2d, 内存状态: <%2d", vpoint, pf_info.serial[vpoint], pageframe[0]);
for (int i = 1; i < PAGEFRAMENUM; ++i) {
if (pageframe[i] == -1) {
printf(", ");
} else {
printf(",%2d", pageframe[i]);
}
}
printf("> ");
// pstate 表示页面是否在内存,如果不在,则需要打印“缺页,缺页率=?”
if (!pstate) {
printf("==>缺页, 缺页率%.1f", pf_info.diseffect * 1.0 / (vpoint + 1) * 100);
}
printf("\n");
}
// FIFO页面置换算法
void FIFO(){
// 初始化页框信息
for (int i = 0; i < PAGEFRAMENUM; i++) {
pageframe[i] = -1;
}
vpoint = rpoint = 0; // 初始化页面访问指针和页面替换指针
pf_info.diseffect = 0; // 初始化缺页次数
pf_info.total_pf = 0; // 初始化页框数
// 对于序列中的每个页执行算法
for (vpoint = 0; vpoint < pf_info.total_pn; vpoint++) {
int pstate = findpage(); // 页是否在内存
// 若页不存在,则装入页面
if (!pstate) {
if (pf_info.total_pf < PAGEFRAMENUM) {
pf_info.total_pf += 1;
}
pageframe[rpoint] = pf_info.serial[vpoint];
rpoint = (rpoint + 1) % PAGEFRAMENUM;
pf_info.diseffect += 1; // 缺页次数加1
}
displayinfo(pstate); // 显示当前状态
Sleep(100); // 延时100ms
} // 置换算法循环结束
float x = pf_info.diseffect * 1.0 / pf_info.total_pn * 100;
printf("\n总缺页数=%d, 总缺页率=%.1f\n\n\n", pf_info.diseffect, x);
// 结果写入文件
ofstream outFile;
outFile.open("结果.txt", ios::app) ;
outFile << PAGEFRAMENUM<< "," << fixed << setprecision(1) << x << endl;
outFile.close();
}
//查找页面是否在内存,1为在内存,0为不在即缺页
int findpage() {
for (int i = 0; i < PAGEFRAMENUM; i++) {
// 页面存在
if (pageframe[i] == pf_info.serial[vpoint]) {
return 1;
}
}
return 0; // 页面不存在,缺页
}
int main() {
// system("cls") ;
createps(); // 随机生成访问序列
// 打印出每个页面信息
cout << "==================页面访问序列==================" << endl;
for(int i = 0; i < pf_info.total_pn; i++) {
cout << pf_info.serial[i] << "\t";
if( (i+1) % 10 == 0 || i == pf_info.total_pn-1) cout << endl;
}
cout << "===============================================" << endl;
do {
cout << "please input pysical page number:" << endl;
scanf("%d", &PAGEFRAMENUM);
cout << "\n------------------FIFO Algorithm: "<< PAGEFRAMENUM << "frames---------------------\n" << endl;
FIFO(); // 执行FIFO置换算法
} while(PAGEFRAMENUM > 0);
}
五、运行结果
5.1 随机生成内存序列
实验中,我设置随机页面序列长度为30~50,每个序列值为0~9。某次运行中,生成的随机页面访问序列长度为35,具体如下图所示:
图2 随机生成内存序列截图
5.2 中间运行结果
图3 中间运行结果截图
当物理页面数目设置为5时,其总缺页数为16,总缺页率为47.1。
5.3 运行结果
我进行了两组数据测试,两组数据都使随机访问页面序列长度为35,具体序列值如5.1中图片与下图4所示。
图4 随机生成内存序列截图2
将物理页面值从1开始遍历至13,得到缺页率结果如下图5和图6所示。
图5 第一次数据结果 图6 第二次数据结果
5.4 物理页面/缺页率曲线图
将结果一与结果二的.txt文件修改为.csv文件,利用Excel打开后绘制折线图,如下图7和图8所示。
图7 第一次数据折线图
图8 第二次数据折线图
从折线图中不难看出,对于页面序列长度为35的随机访问序列,当物理页面数量达到8时,缺页率不再发生明显变化。
六、结论心得
本次实验,我通过编写C++程序实现了FIFO页面置换算法。此算法直接淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。其实现的核心思想在于:把已进入内存的页面按先后顺序连成一个队列,设置一个替换指针指向最久调入的页面,若在此队列中已存在,则不进行替换;否则替换指针所指向的页面出队,新调用的页面入队。实验中,我们首先定义了页面信息结构和队列指针等数据结构,然后分析算法原理、绘制程序流程图,继而在给的提示代码下完成模拟程序的编写。
经过测试,程序可以随机生成页面访问序列,并成功实现FIFO页面置换,正确计算缺页率。最终,通过对实验结果绘制折线图,不难发现在页面访问序列长度为35时,物理页面达到8时,缺页率不再发生明显变化。
作为最早出现的置换算法,我们可以在实验过程中发现,它实现起来比较简单,不需要硬件的支持,不需要增加系统的成本;但是,没有考虑到缓存页面被使用的情况,很可能将一个被频繁访问的页面清除出缓存。
总之,这次实验不仅锻炼了我的实践能力,也让我更加深刻地理解了FIFO页面置换算法的原理,受益匪浅。