题目
(1)通过随机数产生一个指令序列,共320条指令。其地址按下述原则生成:
②25%的指令是均匀分布在前地址部分;
③25%的指令是均匀分布在后地址部分;
具体的实施方法是:
- 在[0,319]的指令地址之间随机选取一起点m;
- 顺序执行一条指令,即执行地址为m+1的指令;
- 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’;
- 顺序执行一条指令,其地址为m’+1;
- 在后地址[m’+2,319]中随机选取一条指令并执行;
- 重复①-⑤,直到执行320次指令。’d
(2)将指令序列变换成页地址流,设:
①页面大小为1K;
②用户内存容量为4页到32页;
③用户虚存容量为32K。
在用户虚存中,按每页存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第0条—第9条指令为第0页(对应虚存地址为[0,9]);
第10条—第19条指令为第1页(对应虚存地址为[10,19]);
。。。。。。。。。。。。。。。。。。。。。
第310条—第319条指令为第31页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成32页。
①FIFO先进先出的页面淘汰算法
②LRU最近最少使用页面淘汰算法
③OPT最佳页面淘汰算法
④LFU最不经常使用页面淘汰算法
⑤NUR最近没有使用页面淘汰算法
吐槽
看了大多数博客,发现抄袭抄的一样,而且错误百出,错的也错的一样,决定自己写一个比较好的系统。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int order[320];
double T_FIFO();
double T_LRU();
double T_OPT();
double T_LFU();
double T_NUR();
typedef struct{
int t_id;//指令地址
int page;//对应页号
}mapping;
mapping mapp[320];//320映射表
typedef struct{//页号对应的记录
int page;//对应页号
int state;//状态位----是否在内存
int visit;//访问字段---最近被访问几次
//int revise;//修改位 ---调入内存后是否修改过,本题不需要此参数
int t_id;//指令地址----外存地址
}page_data;
page_data pg_da[32];//页表信息
//内存大小为4-32
mapping get_mapping(int id){//通过id返回mapping
int pa=id/10;
mapping temp;
temp.page=pa;
temp.t_id=id;
return temp;
}
void ge_ma(){//赋值
for(int i=0;i<320;i++){
mapping temp=get_mapping(order[i]);
mapp[i].page=temp.page;
mapp[i].t_id=temp.t_id;
}
}
void show_ge_ma(){//打印
cout<<"1: "<<" ";
for(int i=0;i<320;i++){
cout<<"||"<<"t_id="<<mapp[i].t_id<<" "<<"page="<<mapp[i].page<<"||"<<" ";
if(i%4==0&&i!=0){
cout<<endl;
cout<<(i/4)+1<<": "<<" ";
}
}
}
void get_pg_da(){
for(int i=0;i<320;i++){
pg_da[i].t_id=order[i];
pg_da[i].page=order[i]/10;
pg_da[i].state=0;//默认不在内存
pg_da[i].visit=0;//默认
}
}
void show_pg_da(){
cout<<"1: "<<" ";
for(int i=0;i<320;i++){
cout<<"||"<<"t_id="<<pg_da[i].t_id<<" "<<"page="<<pg_da[i].page<<" ";
cout<<"state="<<pg_da[i].state<<" "<<"visit="<<pg_da[i].visit<<"||"<<" ";
cout<<endl<<i+1<<": "<<" ";
}
}
void init_order(){//初始化order数组
memset(order,0,sizeof(order));//使用order全部初始化为0
//1.生成随机的m
//设置种子
srand(time(0));//随机种子
//缺点--->srand(time(0))太过依赖时间,在一个相近的时间段内,大多数随机数其实是相近的
//2.赋值
for(int i=0;i<320;i=i+4){//不是加一是为了避免重复覆盖
int m=rand()%320;//随机有m
order[i]=m+1;//指令1-->顺序执行一条指令,即执行地址为m+1的指令
order[i+1]=rand()%(m+1);//指令2-->在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m'
order[i+2]=order[i+1]+1;//指令3-->顺序执行一条指令,其地址为m'+1;
//指令4-->在后地址[m'+2,319]中随机选取一条指令并执行
int temp=0;
while(temp<order[i+2]+1){//判断是否大于m'+2
temp=rand()%320;
}
order[i+3]=temp;
}
}
void show_order(){//打印order数组
cout<<"1: "<<" ";
for(int i=0;i<320;i++){
cout<<order[i]<<" ";
if(i%10==0&&i!=0){
cout<<endl;
cout<<(i/10)+1<<": "<<" ";
}
}
}
//设置内存大小变量,默认为4,由一个函数对大小进行调节
int t_memory=4;
void chage_t_memory(int num){
if(num<4||num>32){
cout<<"Input error! Please try again";
}
else{
t_memory=num;
}
}
double hit_rate(int num){//传入为函数的缺页次数
double temp=1.0-num*1.0/320.0;
return temp;
}
//①FIFO先进先出的页面淘汰算法
double T_FIFO(){//返回命中率
//设置内存
int mem[t_memory];
memset(mem,-1,sizeof(mem));//设置数组初值为-1
int loss_page=0;//统计缺页
int add_num=t_memory;//填入数据让内存填满时的数据
int Mpointer=0;//填入指针默认为0;
int Fpointer=0;//先出指针默认为0;
//初始化数据
//get_pg_da();
for(int i=0;i<320;i++){//填入数据
/*double temp1=hit_rate(loss_page);
cout<<"i="<<i-1<<" "<<"vaule="<<temp1<<" "<<"loss_page="<<loss_page<<endl;*/
//检测内存中是否有这个页
int flag=-1;//1为重复
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
flag=1;
break;
}
}
if(i<add_num&&flag==-1){
//没有满,且不重复,直接填入
mem[Mpointer]=mapp[i].page;//填入对应的页
loss_page++;
Mpointer++;
continue;
}
if(i<add_num&&flag!=-1){
//没有满,重复,增加add_num
add_num++;
continue;
}
//填满了--开始置换算法
//①FIFO先进先出
if(flag==1){
continue;
}
else{
loss_page++;
mem[Fpointer]=mapp[i].page;
Fpointer=Fpointer+1;
if(Fpointer>=t_memory){
Fpointer=0;
}
}
}
//计算命中率
double temp=hit_rate(loss_page);
return temp;
}
//②LRU最近最少使用页面淘汰算法
double T_LRU(){//返回命中率
//设置内存
int mem[t_memory];
memset(mem,-1,sizeof(mem));//设置数组初值为-1
int loss_page=0;//统计缺页
int add_num=t_memory;//填入数据让内存填满时的数据
int Mpointer=0;//填入指针默认为0;
int Fpointer=0;//先出指针默认为0;
int mem_lru[t_memory];//记录次数,实验立刻变1,否每一轮便加一
memset(mem_lru,0,sizeof(mem_lru));//设置数组初值为0
//初始化数据
//get_pg_da();
for(int i=0;i<320;i++){//填入数据
/*double temp1=hit_rate(loss_page);
cout<<"i="<<i-1<<" "<<"vaule="<<temp1<<" "<<"loss_page="<<loss_page<<endl;*/
//检测内存中是否有这个页
int flag=-1;//1为重复
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
flag=1;
break;
}
}
if(i<add_num&&flag==-1){
//没有满,且不重复,直接填入
mem[Mpointer]=mapp[i].page;//填入对应的页
mem_lru[Mpointer]=1; //对应的lru计数器变成1
loss_page++;
Mpointer++;
continue;
}
if(i<add_num&&flag!=-1){
//没有满,重复,增加add_num
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
mem_lru[j]=1; //对应使用变为1
break;
}
}
add_num++;
continue;
}
//填满了--开始置换算法
//①T_LRU最近最少使用页面淘汰算法
if(flag==1){
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
mem_lru[j]=1; //对应使用变为1
break;
}
}
continue;
}
else{
loss_page++;
//找到最少使用的那个数
int sol=0;
int min_vaule=mem[0];//设第一个为最小值
for(int j=0;j<t_memory;j++){
if(mem_lru[j]<min_vaule){
sol=j;
min_vaule=mem[j];
}
}
//替换
mem[sol]=mapp[i].page;
mem_lru[sol]=1;
//开始加
}
//每次循环的累加
for(int j=0;j<t_memory;j++){
if(mem_lru[j]==0){//表示还没有装填
continue;
}
else{
mem_lru[j]++;
}
}
}
//计算命中率
double temp=hit_rate(loss_page);
return temp;
}
//3.OPT最佳页面淘汰算法
double T_OPT(){//返回命中率
//设置内存
int mem[t_memory];
memset(mem,-1,sizeof(mem));//设置数组初值为-1
int loss_page=0;//统计缺页
int add_num=t_memory;//填入数据让内存填满时的数据
int Mpointer=0;//填入指针默认为0;
int Fpointer=0;//先出指针默认为0;
//初始化数据
//get_pg_da();
for(int i=0;i<320;i++){//填入数据
/*double temp1=hit_rate(loss_page);
cout<<"i="<<i-1<<" "<<"vaule="<<temp1<<" "<<"loss_page="<<loss_page<<endl;*/
//检测内存中是否有这个页
int flag=-1;//1为重复
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
flag=1;
break;
}
}
if(i<add_num&&flag==-1){
//没有满,且不重复,直接填入
mem[Mpointer]=mapp[i].page;//填入对应的页
loss_page++;
Mpointer++;
continue;
}
if(i<add_num&&flag!=-1){
//没有满,重复,增加add_num
add_num++;
continue;
}
//填满了--开始置换算法
//3 OPT
if(flag==1){
continue;
}
else{
loss_page++;
//遍历寻找以后最长时间不会使用的数据
int mem_opt[t_memory];//该数组为了找到最少使用的页
memset(mem_opt,0,sizeof(mem_opt));//初值为0,1为使用
//开始遍历
//2种情况
//1--->内存比较小,在后续寻找中所有的页都找到了,或者只有一个没有找到
//2--->内存比较大,多个找不到 ---第一个找不到的进行替换。
//===>总结,对第一个找到不是0的进行替换
int ans=0;
int lag=0;
for(int j=i+1;j<320;j++){
if(lag=1){
break;
}
for(int k=0;k<t_memory;k++){
if(mem[k]==mapp[j].page&&mem_opt[k]==0){//重复且没有覆盖过
mem_opt[k]=1;//覆盖不选它
ans++;
}
if(ans==t_memory-1){//找到了t_memory-1个,最后一个不需要了
lag=1;
break;
}
}
}
//int fflag=0;
//找到第一个不是0的,如果都是,去除第一个
for(int j=0;j<t_memory;j++){
if(mem_opt[j]==0){
mem[j]=mapp[i].page;
//fflag=1;
break;
}
}
/*
if(fflag==0){
mem[0]=mapp[i].page;
}
*/
}
}
//计算命中率
double temp=hit_rate(loss_page);
return temp;
}
//④LFU最不经常使用页面淘汰算法
double T_LFU(){//返回命中率
//设置内存
int mem[t_memory];
memset(mem,-1,sizeof(mem));//设置数组初值为-1
int loss_page=0;//统计缺页
int add_num=t_memory;//填入数据让内存填满时的数据
int Mpointer=0;//填入指针默认为0;
int Fpointer=0;//先出指针默认为0;
int mem_lfu[t_memory];//记录频次
memset(mem_lfu,0,sizeof(mem_lfu));
//初始化数据
//get_pg_da();
for(int i=0;i<320;i++){//填入数据
/*double temp1=hit_rate(loss_page);
cout<<"i="<<i-1<<" "<<"vaule="<<temp1<<" "<<"loss_page="<<loss_page<<endl;*/
//检测内存中是否有这个页
int flag=-1;//1为重复
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
flag=1;
break;
}
}
if(i<add_num&&flag==-1){
//没有满,且不重复,直接填入
mem[Mpointer]=mapp[i].page;//填入对应的页
loss_page++;
Mpointer++;
mem_lfu[Mpointer]++;
continue;
}
if(i<add_num&&flag!=-1){
//没有满,重复,增加add_num
int sol=0;
//int min_vaule=mem[0];//设第一个为最小值
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
sol=j;
break;
}
}
mem_lfu[sol]++;
add_num++;
continue;
}
//填满了--开始置换算法
//LFU
if(flag==1){
int sol=0;
//int min_vaule=mem[0];//设第一个为最小值
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
sol=j;
break;
}
}
mem_lfu[sol]++;
continue;
}
else{
//找到频次最少的
int sol=0;
int min_vaule=mem[0];//设第一个为最小值
for(int j=0;j<t_memory;j++){
if(mem_lfu[j]<min_vaule){
sol=j;
min_vaule=mem[j];
}
}
loss_page++;
mem[sol]=mapp[i].page;
}
}
//计算命中率
double temp=hit_rate(loss_page);
return temp;
}
//⑤NUR最近没有使用页面淘汰算法
double T_NUR(){//返回命中率
//设置内存
int mem[t_memory];
memset(mem,-1,sizeof(mem));//设置数组初值为-1
int loss_page=0;//统计缺页
int add_num=t_memory;//填入数据让内存填满时的数据
int Mpointer=0;//填入指针默认为0;
int Fpointer=0;//先出指针默认为0;
int mem_nur[t_memory];//记录是否访问,实验立刻变1,否则不变
memset(mem_nur,0,sizeof(mem_nur));//设置数组初值为0
//初始化数据
//get_pg_da();
for(int i=0;i<320;i++){//填入数据
/*double temp1=hit_rate(loss_page);
cout<<"i="<<i-1<<" "<<"vaule="<<temp1<<" "<<"loss_page="<<loss_page<<endl;*/
//检测内存中是否有这个页
int flag=-1;//1为重复
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
flag=1;
break;
}
}
if(i<add_num&&flag==-1){
//没有满,且不重复,直接填入
mem[Mpointer]=mapp[i].page;//填入对应的页
mem_nur[Mpointer]=1;//标记
loss_page++;
Mpointer++;
continue;
}
if(i<add_num&&flag!=-1){
//没有满,重复,增加add_num
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
mem_nur[j]=1; //对应使用变为1
break;
}
}
add_num++;
continue;
}
//填满了--开始置换算法
//⑤NUR最近没有使用页面淘汰算法
if(flag==1){
for(int j=0;j<t_memory;j++){
if(mem[j]==mapp[i].page){
mem_nur[j]=1; //对应使用变为1
break;
}
}
continue;
}
else{
//循环遍历
//第一次
int fflag=0;//1为需要第二次遍历
int sol=0;
while(1){
if(mem_nur[Fpointer]==0){
sol=Fpointer;
Fpointer=Fpointer+1;
if(Fpointer>=t_memory){
Fpointer=0;
}
break;
}
else{
mem_nur[Fpointer]=0;
Fpointer=Fpointer+1;
if(Fpointer>=t_memory){
Fpointer=0;
}
}
}
loss_page++;
mem[sol]=mapp[i].page;
}
}
//计算命中率
double temp=hit_rate(loss_page);
return temp;
}
void show(){
for(int i=4;i<=32;i++){
t_memory=i;
cout<<i<<" ";
double temp1=T_FIFO();
cout<<"FIFO:"<<temp1<<" ";
double temp2=T_LRU();
cout<<"LRU:"<<temp2<<" ";
double temp3=T_OPT();
cout<<"OPT:"<<temp3<<" ";
double temp4=T_LFU();
cout<<"LFU:"<<temp4<<" ";
double temp5=T_NUR();
cout<<"NUR:"<<temp5<<endl;
}
t_memory=4;//重置
}
void memu(){
init_order();
ge_ma();
get_pg_da();
cout<<" 欢迎来到***的操作系统第三次实验系统!"<<endl;
cout<<"---------------------------------------------------------------------------------------"<<endl;
//int l=0;
while(1){
cout<<"1->show_order"<<endl;
cout<<"2-> show_mapping"<<endl;
cout<<"3-> show page_data"<<endl;
cout<<"4 -> show FIFO"<<endl;
cout<<"5 -> show LRU"<<endl;
cout<<"6 -> show OPT"<<endl;
cout<<"7 -> show LFU"<<endl;
cout<<"8 -> show NUR"<<endl;
cout<<"9 -> show all"<<endl;
cout<<"42-> change Memory"<<endl;
cout<<"88 -> exit"<<endl;
//
int l;
cin>>l;
if(l==1){
show_order();
cout<<endl;
}
else if(l==2){
show_ge_ma();
cout<<endl;
}
else if(l==3){
show_pg_da();
cout<<endl;
}
else if(l==4){
double temp=T_FIFO();
cout<<temp;
}
else if(l==5){
double temp=T_LRU();
cout<<temp;
}
else if(l==6){
double temp=T_OPT();
cout<<temp;
}
else if(l==7){
double temp=T_LFU();
cout<<temp;
}
else if(l==8){
double temp=T_LFU();
cout<<temp;
}
else if(l==42){
cout<<endl;
cout<<"现在的内存大小为:"<<t_memory<<endl;
cout<<endl<<"您要修改为多少?(4-32)"<<endl;
cout<<endl<<"现在请输入这个数:";
int num;
cin>>num;
chage_t_memory(num);
cout<<endl<<endl;
cout<<"修改完成,现在的内存大小为:"<< t_memory<<endl;
}
else if(l==88){
cout<<endl;
cout<<"谢谢使用!"<<endl;
break;
}
cout<<endl<<endl;
cout<<"---------------------------------------------------------------------------------------"<<endl;
}
}
int main(){
memu();
return 0;
}