页面置换算法的模拟(FIFO,LRU和OPT)

设计一个虚拟存储区和内存工作区,并使用下述常用页面置换算法计算访问命中率。

(1)先进先出算法(FIFO)

(2)最近最少使用算法(LRU)

(3)最优置换算法(OPT)

实验要求:

(1)通过随机数产生一个指令序列,共320条指令。

(2)将指令序列转换成页面序列。

    ①页面大小为1KB;

    ②用户内存容量为4~32页;

    ③用户虚存容量为32KB。

    ④在用户虚存中,按每页存放10条指令排列虚存地址,即320条指令存在32个页面中。

(3)计算并输出不同置换算法在不同内存容量下的命中率。

    命中率计算公式为:

           命中率 = 1 – 页面访问失败次数 / 页面总数

#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<random>
#include<algorithm>

const int PAGE_SIZE = 1024;
const int INSTRUCTION_COUNT = 320;
const int PAGE_NUM = 32;

double FIFO(std::vector<int>sequence, int page_num) {
	int falut_num = 0;//缺页的次数
	std::queue<int>page_queue;
	int free_num = page_num;
	//页面指令  sequence[i]表示第i条页面指令是要去的页面的编号
	std::set<int>p;
	for (int i = 0; i < INSTRUCTION_COUNT; i++) {
		int x = sequence[i];//要去编号为x的页面
		if (p.count(x))//该页面已经存在
			continue;
		else {
			//该页面不存在且还有剩余空间
			if (free_num > 0) {
				page_queue.push(x);
				p.insert(x);
				free_num--;
			}
			else {
				falut_num++;
				int a = page_queue.front();
				p.erase(a);
				page_queue.pop();
				page_queue.push(x);
				p.insert(x);
			}
		}
	}
	return  double(1 - falut_num * 1.0 / INSTRUCTION_COUNT);
}
double LRU(std::vector<int>sequence, int page_num) {
	//符合能插头且删尾的数据结构,那必然是...deque?no no no,那必然是vector
	std::vector<int>p;
	std::set<int>pp;
	int flaut_num = 0;
	int free_num = page_num;
	for (int i = 0; i < INSTRUCTION_COUNT; i++) {
		int x = sequence[i];
		if (pp.count(x)) {
			auto a = find(p.begin(), p.end(), x);//找到这个元素的位置
			int aa = *a;
			p.erase(a);//删除原来的位置
			p.insert(p.begin(), aa);//插到头部位置
		}
		else {
			if (free_num > 0) {//有空余空间
				free_num--;
				p.insert(p.begin(), x);
				pp.insert(x);
			}
			else {
				int a = p.back();
				pp.erase(a);
				pp.insert(x);
				p.pop_back();
				p.insert(p.begin(), x);
				flaut_num++;
			}
		}
	}
	return  double(1 - flaut_num * 1.0 / INSTRUCTION_COUNT);
}

double OPT(std::vector<int>sequence, int page_num) {
	std::set<int>p;
	int free_num = page_num;
	int falut_num = 0;
	for (int i = 0; i < INSTRUCTION_COUNT; i++) {
		int x = sequence[i];
		if (p.count(x))
			continue;
		else {
			if (free_num > 0) {
				free_num--;
				p.insert(x);
			}
			else {
				falut_num++;
				std::map<int, int>pp;
				for (int e = i + 1; e < INSTRUCTION_COUNT; e++) {
					int a = sequence[e];
					if (p.count(a)&&!pp.count(a)) {
						pp[a] = e;
						if (pp.size() == p.size())
							break;
					}
				}
				int a = 0;
				if (pp.size() == p.size()) {
					int b = 0;
					for (auto e : pp) {
						if (e.second > b) {
							b = e.second;
							a = e.first;
						}
					}
				}
				else {
					for (auto e : pp) {
						if (!p.count(e.first)) {
							a = e.first;
							break;
						}
					}
				}
				p.erase(a);
				p.insert(x);
			}
		}
	}
	return double(1 - falut_num * 1.0 / INSTRUCTION_COUNT);
}

void see_sequence(std::vector<int>seqence) {
	for (auto i : seqence)
		std::cout << i << " ";
	std::cout << std::endl;
}

void init(std::vector<int>& sequence,int* seqence2) {
	for (int i = 0; i < INSTRUCTION_COUNT; i++) {
		sequence[i] = rand() % INSTRUCTION_COUNT / 10;
		seqence2[i] = sequence[i];
	}
}

inline void menu() {
	printf("*******************************************\n");
	printf("* 原神怎么你了 原神怎么你了 原神怎么你了  *\n");
	printf("* 1.查看页面序列内容                      *\n");
	printf("* 2.页面置换算法,启动                    *\n");
	printf("* 3.重新生成页面序列                      *\n");
	printf("* 4.exit                                  *\n");
	printf("*******************************************\n");
	printf("请从1-4中选择按键:\n");
}

int main()
{
	int page[PAGE_NUM]; int sequence2[INSTRUCTION_COUNT];
	std::vector<int>sequence(INSTRUCTION_COUNT);//用户虚存
	srand(time(NULL));//设置随机数
	init(sequence,sequence2);
	while (true) {
		menu();
		int op;
		std::cin >> op;
		if (op == 3)
			init(sequence,sequence2);
		else if (op == 1)
			see_sequence(sequence);
		else if (op == 2) {
			std::cout << "内存大小	FIFO			LRU			OPT" << std::endl;
			for (int i = 4; i <= 32; i++) {
				double a = FIFO(sequence, i);
				double b = LRU(sequence, i);
				double c = OPT(sequence, i);
				printf("%d\t\t%f\t\t%f\t\t%f\n", i, a, b, c);
				//std::cout << a << " " << aa << std::endl;
			}
		}
		else if (op == 4)
			break;
	}
	return 0;
}

 

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值