#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;
}
操作系统实验--存储管理--页面置换算法--FIFO and LRU c++实现
最新推荐文章于 2022-12-21 11:53:19 发布