操作系统实验三 存储管理

题目

(1)通过随机数产生一个指令序列,共320条指令。其地址按下述原则生成:

①50%的指令是顺序执行的;

②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页。

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

①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;
}

  • 8
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
(1)通过随机数产生一个指令序列320指令指令地址下述原则生成: ①、 50%的指令是顺序执行的; ②、 25%的指令是均匀分布在前地址部分; ③、 25%的指令是均匀分布在后地址部分。 具体的实施方法是: ① 在[0,319]的指令地址之间随机选取一起点m; ② 顺序 执行一指令,即执行地址为m+1的指令; ③ 在前地址[0,m+1]中随机选取一指令并执行,该指令地址为m’; ④ 顺序执行一指令,其地址为m’+1; ⑤ 在后地址[m’+2,319]中随机选取一指令并执行; ⑥ 重复上述步骤,直至执行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) 计算并输出下述各种算法在不同的内存容量下的命中率。 ① 先进先出的算法(FIFO); ② 最近最少使用算法(LRR); ③ 最佳淘汰法(OPT):先淘汰最不常用的页地址; ④ 最少访问页面算法(LFR); ⑤ 最近不经常使用算法(NUR)。 其中③和④为选择内容。 命中率=1-(页面失效次数)/(页地址流长度) 在本实验中,页地址流的长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。
原创代码+报告(用的是数组)   设计一个请求页式存储管理方案。并编写模拟程序实现之。要求包含:   1.过随机数产生一个指令序列320指令。其地址下述原则生成:   ①50%的指令是顺序执行的;   ②25%的指令是均匀分布在前地址部分;   ③25%的指令是均匀分布在后地址部分;   #具体的实施方法是:      在[0,319]的指令地址之间随机选区一起点M;      顺序执行一指令,即执行地址为M+1的指令;      在前地址[0,M+1]中随机选取一指令并执行,该指令地址为M’;      顺序执行一指令,其地址为M’+1;      在后地址[M’+2,319]中随机选取一指令并执行;      重复A—E,直到执行320指令。   2.指令序列变换成页地址流    设:(1)页面大小为1K;       用户内存容量为4页到32页;        用户虚存容量为32K。   在用户虚存中,按每K存放10指令排列虚存地址,即320指令在虚存中的存放方式为:    第0—第9指令为第0页(对应虚存地址为[0,9]);    第10—第19指令为第1页(对应虚存地址为[10,19]);    。。。。。。。。。。。。。。。。。。。。。    第310—第319指令为第31页(对应虚存地址为[310,319]);   按以上方式,用户指令可组成32页。   3. 计算并输出下述各种算法在不同内存容量下的命中率。      FIFO先进先出的算法      LRR最近最少使用算法      OPT最佳淘汰算法(先淘汰最不常用的页地址)      LFR最少访问页面算法      NUR最近最不经常使用算法
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值