请求分页储存管理的页置换算法模拟

详细知识点可以参考请求分页虛拟存储管理及页面置换算法

请求分页储存管理

请求分页系统是建立在基本分页系统的基础上,增加了请求调页功能页面置换功能形成的页式虚拟储存管理。(必须要需要的硬件和软件支持。)

页置换算法

常用的页置换算法有:

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

效果

FIFO
随机OPT

代码模拟

主要包含生成随机访问序列和打印表示访问状态的表格,所以比较繁杂。可以下载打包好的模拟程序

// LRU算法模拟

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>

using namespace std;

typedef struct {
	int visit;
	vector<int> block;
	bool loss;
	bool replace;
}TableItem;

void printTable(vector<TableItem> history, unsigned int blockCount);
void FIFO(int blockCount, vector<int> & visit);
void OPT(int blockCount, vector<int> & visit);
void LRU(int blockCount, vector<int> & visit);

void scan(int & blockCount, vector<int> & visit) {
	cout << "1.随机生成访问序列" << endl;
	cout << "2.手动输入序列" << endl;
	int op;
	while (true)
	{
		cout << "请选择:" << endl;
		cin >> op;
		if (op == 1 || op == 2)break;
	}
	if (op == 1) {
		int n, num;
		cout << "请输入内存物理块数:" << endl;
		cin >> blockCount;
		cout << "请输入虚页的个数:" << endl;//0 -- n-1
		cin >> n;
		cout << "请输入虚页访问次数:" << endl;
		cin >> num;
		//生成随机访问序列
		visit.clear();
		cout << "生成的随机序列为:" << endl;
		for (int i = 0; i < num; i++) {
			int ran = (int)(n - 1)*rand() / (RAND_MAX + 1);
			visit.push_back(ran);
			cout << ran << " ";
		}
		cout << endl;
	}
	else if (op == 2) {
		cout << "请输入内存物理块数:" << endl;
		cin >> blockCount;
		cout << "请输页面访问序列:(最后一个数据回车后 输入 Ctrl Z 回车结束输入)" << endl;
		visit.clear();
		while (!cin.eof()) {
			int v;
			cin >> v;
			if (cin.fail()) break;
			visit.push_back(v);
		}
	}
}
int main()
{
	srand((int)time(0));  // 产生随机种子
	//4 3 2 1 4 3 5 4 3 2 1 5
	int blockCount = 3;
	vector<int> visit = { 4,3,2,1,4,3,5,4,3,2,1,5 };
	int op;
	while (true)
	{
		cin.clear();
		cin.sync();
		cout << "请选择算法:" << endl;
		cout << "1.FIFO" << endl;
		cout << "2.OPT" << endl;
		cout << "3.LRU" << endl;
		cout << "4.退出" << endl;
		cin >> op;
		switch (op) {
		case 1:
			scan(blockCount, visit);
			cout << "FIFO" << endl;
			FIFO(blockCount, visit);
			break;
		case 2:
			scan(blockCount, visit);
			cout << "OPT" << endl;
			OPT(blockCount, visit);
			break;
		case 3:
			scan(blockCount, visit);
			cout << "LRU" << endl;
			LRU(blockCount, visit);
			break;
		case 4:
			exit(0);
		}
	}
	system("pause");
}

//j就是在FIFO基础上 在访问过存在的序列时调整一下序列的位置
void LRU(int blockCount, vector<int> & visit) {
	vector<TableItem> history;
	int loss = 0;
	vector<int> block;
	for (int & i : visit) {
		TableItem item;
		item.visit = i;
		item.loss = false;
		item.replace = false;
		//块内不包含
		vector<int>::iterator it = find(block.begin(), block.end(), i);
		if (it == block.end()) {
			//如果块满了删除第一个进入的
			if (block.size() == blockCount) {
				block.pop_back();
				item.replace = true;
			}
			loss++;
			block.insert(block.begin(), i);
			item.loss = true;
		}
		else {
			//如果有 则把他放第一个
			block.erase(it);
			block.insert(block.begin(), i);
		}
		item.block = block;
		history.push_back(item);
	}

	printTable(history, blockCount);
	cout << "缺页次数:" << loss << ' ' << "缺页率:" << float(loss) / visit.size() * 100 << '%' << endl;;
}

//OPT
//根据后blockCount个序列预测 不足blockCount按剩余的序列预测
//如果序列最后几位都预测不到 默认置换块首的那一个 这里可能有待细化
void OPT(int blockCount, vector<int> & visit) {
	vector<TableItem> history;
	int loss = 0;
	vector<int> block;
	for (unsigned int i = 0; i < visit.size(); i++) {
		TableItem item;
		item.visit = visit[i];
		item.loss = false;
		item.replace = false;
		//块内不包含
		if (find(block.begin(), block.end(), visit[i]) == block.end()) {
			//如果块满了 根据后blockCount步预测
			if (block.size() == blockCount) {
				bool rep = false;
				auto step = blockCount;
				if (i + 1 + blockCount > visit.size())step = visit.size() - i - 1;
				for (unsigned int k = 0; k < block.size(); k++) {
					unsigned int j = i + 1;
					for (; j < i + 1 + step; j++) {
						if (block[k] == visit[j]) {
							break;
						}
					}
					if (j == i + 1 + step) {
						rep = true;
						block[k] = visit[i];

						item.replace = true;
						break;
					}
				}
				//如果预测的都命中 选最后一个置换
				if (rep == false) {
					item.replace = true;
					block.pop_back();
					block.push_back(visit[i]);
				}
			}
			else {
				block.push_back(visit[i]);
			}
			loss++;
			item.loss = true;
		}
		item.block = block;
		history.push_back(item);
	}

	printTable(history, blockCount);
	cout << "缺页次数:" << loss << ' ' << "缺页率:" << float(loss) / visit.size() * 100 << '%' << endl;
}

//FIFO
void FIFO(int blockCount, vector<int> & visit) {
	vector<TableItem> history;
	int loss = 0;
	vector<int> block;
	for (int & i : visit) {
		TableItem item;
		item.visit = i;
		item.loss = false;
		item.replace = false;
		//块内不包含
		if (find(block.begin(), block.end(), i) == block.end()) {
			//如果块满了删除第一个进入的
			if (block.size() == blockCount) {
				block.pop_back();
				item.replace = true;
			}
			loss++;
			block.insert(block.begin(), i);
			item.loss = true;
		}
		item.block = block;
		history.push_back(item);
	}

	printTable(history, blockCount);
	cout << "缺页次数:" << loss << ' ' << "缺页率:" << float(loss) / visit.size() * 100 << '%' << endl;
}


void printTable(vector<TableItem> history, unsigned int blockCount) {
	cout.setf(std::ios::left);
	cout.width(12);
	cout << "页访问顺序" << '\t';
	for (TableItem item : history) {
		cout << item.visit << "  ";
	}
	cout << endl;
	cout.width(10);
	cout << "内存块数=";
	cout.width(2);
	cout << blockCount << '\t';
	for (unsigned int i = 0; i < blockCount; i++) {
		if (i != 0) {
			cout.width(12);
			cout << " " << '\t';
		}
		for (TableItem item : history) {
			cout.width(2);
			if (item.block.size() > i) {
				cout << item.block[i];
			}
			else {
				cout << ' ';
			}
			cout << " ";
		}
		cout << endl;
	}
	cout.width(12);
	cout << "缺页" << '\t';
	for (TableItem item : history) {
		cout.width(2);
		cout << (item.loss ? "√" : " ");
		cout << " ";
	}
	cout << endl;
	cout.width(12);
	cout << "置换" << '\t';
	for (TableItem item : history) {
		cout.width(2);
		cout << (item.replace ? "√" : " ");
		cout << " ";
	}
	cout << endl;
}

  • 10
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Java图形化界面实现以下要求,我上传给大家一同分享。 通过随机数产生一个指令序列,共 320 条指令,指令的地址按下述原则生成: (1):在[0,319]的指令地址之间随机选取一起点 m。 (2):顺序执行一条指令,即执行地址为 m+1 的指令 。 (3):在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为 m' 。 (4):顺序执行一条指令,其地址为 m'+1。 (5):在后地址[m'+2,319]中随机选取一条指令并执行。 (6):重复步骤 (1)—(6),直到生成 320 条指令。 2、将指令序列转换为页地址流,比如:页面大小为 1K,用户内存容量 4 页到 32 页,用户虚存容量为 32K;在用户虚存中,按每 K存放 10 条指令排列虚存地址。即 320 条指令在虚存中的存放方式为: 第 0 条-第 9 条指令为第 0 页(对应虚存地址为[0,9])。 第 10 条-第 19 条指令为第 1 页(对应虚存地址为[10,19]) 。 ……………………………… 第 310 条-第 319 条指令为第 31页(对应虚存地址为[310,319])。 按以上方式,用户指令可组成 32页。 3、页面大小的取值范围分别为 1K,2K,4K,8K,16K;按照页面大小将指令地址转化为页号;对于相邻相同的页号,合并为一个。 4、分配给程序的内存块数取值范围为 1 块、2块,一直到程序的页面数。 5、分别采用 FIFO 和 LRU 算法对页号序列进行调度,并计算出对应的缺页中断率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值