存储管理
1.实验目的
存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
2.实验内容与要求
(1) 通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。
页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。
在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。
(2) produce_addstream通过随机数产生一个指令序列,共320条指令。
A、 指令的地址按下述原则生成:
1) 50%的指令是顺序执行的
2) 25%的指令是均匀分布在前地址部分
3) 25%的指令是均匀分布在后地址部分
B、 具体的实施方法是:
1) 在[0,319]的指令地址之间随机选取一起点m;
2) 顺序执行一条指令,即执行地址为m+1的指令;
3) 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’;
4) 顺序执行一条指令,地址为m’+1的指令
5) 在后地址[m’+2,319]中随机选取一条指令并执行;
6) 重复上述步骤1)~5),直到执行320次指令
C、 将指令序列变换称为页地址流
在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第0条~第9条指令为第0页(对应虚存地址为[0,9]);
第10条~第19条指令为第1页(对应虚存地址为[10,19]);
。。。。。。
第310条~第319条指令为第31页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成32页。
(3) 计算并输出下属算法在不同内存容量下的命中率。
1) 先进先出的算法(FIFO);
2) 最近最少使用算法(LRU);
3.流程图与模块调用
4.实验分析
本次实验所实现的是页面置换算法,实现了先进先出算法(FIFO)和最近最少使用算法(LRU)。
FIFO算法:
如果需要置换页面,则先置换内存中最先进入的页面,依次运行。这种算法看起来很普通,但是会发生与实际情况不符的状态,即Belady现象(随着内存块分配的增加,该算法的缺页率会升高)。
LRU算法:
如果需要置换页面,则先置换出内存中,最近未被使用的页面,可以从当前页面从后往前搜,找到内存中已经存在的,离当前最远使用的页面即可,将该页面置换出。这个算法实际情况中,实现起来需要进行排序操作,实现起来比较复杂,操作系统需要用硬件进行实现。
5.运行情况
6.实验体会
通过对这两个算法的实现,可以得到FIFO算法和LRU算法的命中率随着内存块的增加,而增加,这次实验中没有出现Belady现象,说明这种现象只是存在出现的可能性,并不是每次都可以见到。LRU算法在随着内存块的增大时,其命中率也稍微要强于FIFO算法,可能是此次实验中内存块的数量有些小,如果内存块更大的话,命中率可能会更强于FIFO算法。
代码
#include<iostream>
#include<queue>
#include<ctime>
#include<vector>
#include<iomanip>
using namespace std;
vector<int> hlp;//存随机数据
bool pan(queue<int> p, int v)//判断q是否存在v
{
while (!p.empty())
{
if (v == p.front())
return true;
else
p.pop();
}
return false;
}
void FIFO(int s)//先进先出
{
queue<int> q;//队列
double fault = 0;//缺页次数
for (int i = 0; i < 320; i++)//320次调度
{
if (i!=0 && pan(q, hlp[i]))//如果内存已经存在该页
{
continue;
}
else if (q.size() < s)//如果内存不满
{
q.push(hlp[i]);
fault++;//同样缺页
}
else if (!pan(q, hlp[i]))//如果不存在该页,则需置换页
{
q.pop();
q.push(hlp[i]);
fault++;
}
}
cout << "用户内存为" << s << "时,命中率为" << (1 - (fault / 320)) << endl;
}
void LRU(int s)//最近最少使用算法
{
vector<int> q;//采用vector
double fault = 0;
for (int i = 0; i < 320; i++)
{
if (i!=0 && find(q.begin(),q.end(),hlp[i])!=q.end())//如果内存已存在该页
{
q.erase(find(q.begin(), q.end(), hlp[i]));//删除该页
q.push_back(hlp[i]);//加入到该数组末尾
}
else if (q.size() < s)//内存不满
{
q.push_back(hlp[i]);
fault++;//缺页
}
else if (find(q.begin(), q.end(), hlp[i]) == q.end())//内存未找到该页
{
q.erase(q.begin());//删除最近最少未使用
q.push_back(hlp[i]);
fault++;
}
}
cout << "用户内存为" << s << "时,命中率为" << (1 - fault / 320) << endl;
}
int main()
{
cout << "Start memory management." << endl;
cout << "Producing address flow,wait for while,please." << endl;
srand((int)time(NULL));
cout << "生成指令队列:" << endl;
for (int i = 0; i < 320; i++)//根据一定的算法生成随机数
{
int p = rand() % 320;
hlp.push_back(p+1);
cout << setw(3) << p+1 << " ";
i++;
int p1 = rand() % (p + 2);//随机0-(l+1)
hlp.push_back(p1);
cout << setw(3) << p1 << " ";
i++;
hlp.push_back(p1 + 1);
cout << setw(3) << p1+1 << " ";
i++;
int p2 = (rand() % (320 - p1 - 2)) + p1+2;
hlp.push_back(p2);
cout <<setw(3) << p2 << " ";
if ((i+1) % 32 == 0)
cout << endl;
}
cout << "转换为地址:" << endl;
for (int i = 0; i < 320; i++)
{
hlp[i] = hlp[i] / 10;
cout <<setw(3) << hlp[i] << " ";
if ((i + 1) % 32 == 0)
cout << endl;
}
cout << "There are algorithms in the program." << endl;
cout << "1、First in first out algorithm" << endl;
cout<<"2、Least recently used algorithm"<<endl;
int check;
char wg='y';//是否继续选择算法
while (wg == 'y')
{
cout << "Select an algorithm number, please." << endl;
cin >> check;
if (check == 1)//先进先出
{
for (int i = 2; i <= 32; i++)
{
FIFO(i);
}
}
else if (check == 2)//最近最少使用
{
for (int i = 2; i <= 32; i++)
{
LRU(i);
}
}
else
{
cout << "there is not the algorithm in the program" << endl;
}
cout << "do you try again with anther algorithm(y/n)"<< endl;
cin >> wg;
}
}