操作系统实验--存储管理--页面置换算法--FIFO and LRU c++实现

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//宏定义,生成指定范围[a,b]之间的随机数
#define Random(a,b) (rand()%(b-0+1)+0)
using namespace std;
class Page_Replace {
public:
	double precent(double h);// 求命中率
	int Instuction[320];// 存储指令流的数组	
	double n;// 命中率	
	Page_Replace();//构造函数用于初始化指令流	
	void Show();// 显示数组初始化情况	
	bool Judge(int *t,int v, int n);// 判断物理空间中刚进来的指令有没有和前面的指令相同的情况,以将要进来的指令v为参数, 如果有相同的,返回false,全不相同,返回true
	int Rpeat;// 该变量用于记录重复指令的下标
private:	
	int F_circle[4];// 随机生成的4个指令	
	int m;// 选取的中间位置
};

double Page_Replace::precent(double h)
{
	n = h / 3.2;
	return n;
}
Page_Replace::Page_Replace()
{
	for (int i = 0;i < 320;i++)// 将Instruction的值先全部初始化为-1
		Instuction[i] = -1;
	
	int k = 0;// k当作Instruction的下标
	srand((unsigned int)time(0));
	for (int i = 0;i < 80;i++)
	{
		m = Random(0, 319);
		F_circle[0] = m + 1;
		F_circle[1] = Random(0, F_circle[1]);
		F_circle[2] = F_circle[1] + 1;
		F_circle[3] = Random(F_circle[2] + 1, 319);
		for (int j = 0;j < 4;j++)
		{
			Instuction[k] = F_circle[j];
			k++;
		}
	}
}
void Page_Replace::Show()
{
	for (int i = 0;i < 320;i++)
		cout << Instuction[i] << "  ";
}

bool Page_Replace::Judge(int *t,int v,int n)//v为指令本身,n为每次比较的元素个数
{
	int i = 0;
	for ( i ;i < n;i++)
	{
		if (t[i] == v)
		{
			Rpeat = i;
			break;
		}	
	}
	if (i == n)
		return true;
	else
		return false;
}


class FIFO :public Page_Replace {// 先进先出算法的类,继承于Page_Replace
public:
	FIFO();
	double Add(int m, int n);// 进行指令流的遍历
private:
	// 计数器,用于计算命中了多少次
	double count_F;
};
FIFO::FIFO() :Page_Replace()
{
	count_F = 0.0;
}

double FIFO::Add(int m, int n)// m的值为大小的上限,n为数组大小
{
	bool jud;
	if (n > m)
	{
		cout << "超出范围!" << endl;
		return 0.0;
	}
	else
	{
		int *t = new int[n];// 定义一个动态数组,用于生成指定大小的数组
		int k = 0;//Instruction的下标
		int v = 0;//用于计算数组中是否已经第一次添加满
		while (v < n)
		{
			t[v] = Instuction[k];

			if (Judge(t, Instuction[k + 1], v + 1) == false)
			{
				count_F++;
				k++;
			}
			else
			{
				k++;
				v++;
			}
		}
		//对后来的指令进行判断,如果在已有的数据里,t数组不变,否则,挨个往前移
		for (int j = 0;j < 320 - k + 1;j++)
		{
			if (Judge(t, Instuction[k], n) == false)
			{
				count_F++;
				k++;
			}
			else
			{
				for (int i = 0;i < 9;i++)
				{
					t[i] = t[i + 1];
				}
				t[9] = Instuction[k];
				k++;
			}
		}
	}
	cout << "FIFO算法命中的数量是:" << count_F << endl;
	return count_F;
}

class LRU :public Page_Replace {
public:
	LRU();
	int Find(int *F_demen, int left, int right);// 比较出在物理块中的所有指令中使用次数最少的指令,参数为物理块的大小
	double Add_L(int m,int n);
private:
	double count_L;
};
LRU::LRU():Page_Replace()
{
	count_L = 0.0;
}

int LRU::Find(int *F_demen,int left,int right)// 使用快速排序法找出最小的值
{
	int key = F_demen[left];//将区间分为两个部分,左边的小于等于右边的
	int i = left, j = right;
	while (i < j)
	{
		while (F_demen[j] >= key && i < j)//从右边开始比较
			j--;
		F_demen[i] = F_demen[j];//如果有位置不对的,将位置进行交换
		while (F_demen[i] <= key && i < j)
			i++;
		F_demen[j] = F_demen[i];
	}
	F_demen[i] = key;
	if (left < i - 1)Find(F_demen,left, i - 1);
	if (i + 1 < right)Find(F_demen,i + 1, right);
	return F_demen[0];//F_demen[0]就是最少使用的指令的下标
}
double LRU::Add_L(int m, int n)// m的值为大小的上限,n为数组大小
{
	bool jud;
	int *q = new int[n];// 定义一个动态数组,记录该进程执行的总次数
	for (int i = 0;i < n;i++)//将其初值都置为0
	{
		q[i] = 0;
	}
	if (n > m)
	{
		cout << "超出范围!" << endl;
		return 0.0;
	}
	else
	{
		int *t = new int[n];// 定义一个动态数组,用于生成指定大小的数组
		int k = 0;//Instruction的下标
		int v = 0;//用于计算数组中是否已经第一次添加满
		while (v < n)
		{
			t[v] = Instuction[k];
			q[v]++;// 出现一次,需要加一

			if (Judge(t, Instuction[k + 1], v + 1) == false)// 说明新来的指令已经存在于页面中
			{
				q[Rpeat]++;
				count_L++;
				k++;
			}
			else
			{
				k++;
				v++;
			}
		}// 此循环结束,数组中已有满n个指令
		// 对于后来的指令,需要进行判断,如果该指令已经存在于物理块中,命中
		for (int j = 0;j < 320 - k + 1;j++)
		{
			if (Judge(t, Instuction[k], n) == false)
			{
				count_L++;
				k++;
			}
			else
			{
				int r = Find(q, 0, 9);
				t[r] = Instuction[k];
				k++;
			}
		}
		cout << "LRU算法命中的数量是:" << count_L << endl;
		return count_L;
	}
}

int main()
{
	FIFO fifo;
	LRU lru;
	fifo.Show();
	double k=fifo.Add(320,100);// 此方法的的原型是double Add(int m, int n);其中参数n代表分配的物理块大小,可以改变;
	double a = lru.Add_L(320, 100);// 同上
	double n=fifo.precent(k);
	double b = lru.precent(a);
	cout << "FIFO的命中率为:" << n << "%" << endl;
	cout << "LRU的命中率为:" << b << "%" << endl;
	system("pause");
	return 0;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值