当前位置:文档之家› 计算机系统结构课程实验报告实验一:存贮层次模拟器

计算机系统结构课程实验报告实验一:存贮层次模拟器

计算机系统结构课程实验报告实验一:存贮层次模拟器计算机系统结构课程实验报告2012—2013 学年第 1 学期学生姓名: 学生班级: 2011179 学生学号: 2011179 指导教师: 孙全红教研室: 计算机系统结构教研室2012年 10月 23日实验一:存贮层次模拟器一、实验目的与要求使学生清楚认识虚拟存贮层次结构,熟练掌握常用的几种存储地址映象与变换方法,以及FIFO、LRU等替换算法的工作全过程。

要求用程序实现任意地址流在存储层次上的命中情况,实验结束后提交源程序和实验说明书。

二、实验内容在模拟器上实现在任意地址流下求出在cache —主存—辅存三层存贮层次上的命中率。

三、实验步骤1(Cache—主存:映像方式可以选择全相联、直接映象、组相联方式;替换算法一般使用LRU算法。

2(要求Cache大小、主存容量、块大小以及组数等可以输入修改。

3(求出命中率;显示替换的全过程;任选一种高级语言来做。

4(要有简洁、易于操作的界面。

四、程序源代码# include <stdio.h># include <iostream.h># include <stdlib.h>struct CacheStruct{int blocknum;int count;};void All_LinkLRU(CacheStruct cs[],int bottom,int stream[],int k,int result[20][20]){int j=0,m=0,max=0,location=0,hitnum=0;cout<<endl;//cout<<"主存访问块流"<<" "<<"是否替换"<<" "<<"是否命中"<<""<<"Cache块存放情况"<<endl;for(int i=0;i<k;i++){if(j<bottom)//Cache块不满{m=0;if(j==0){cs[j].blocknum=stream[i];cs[j].count=0;result[j][i]=stream[i];//result[bottom][i]=0;//result[bottom+1][i]=0;不需要/*cout<<stream[i]<<"\t\t";cout<<"块失效\t\t";cout<<"未命中\t\t";for(int t=0;t<bottom;t++){if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/j++;// continue;}else{while(m<j && cs[m].blocknum!=stream[i]) {cs[m].count++;m++;}if(m==j)//已存在的未命中{cs[j].blocknum=stream[i];cs[j].count=0;result[j][i]=stream[i];//result[bottom][i]=0;// result[bottom+1][i]=0;不需要/*cout<<stream[i]<<"\t\t"; cout<<"块失效\t\t";cout<<"未命中\t\t";for(int t=0;t<bottom;t++) {if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' '; elsecout<<"空 ";}cout<<endl;*/j++;// continue;}else//已存在的命中了{cs[m].count=0;m++;result[bottom+1][i]=0;/*cout<<stream[i]<<"\t\t"; cout<<"无替换\t\t";cout<<"命中\t\t";for(int t=0;t<bottom;t++) {if(cs[t].blocknum!=-1) cout<<cs[t].blocknum<<' '; elsecout<<"空 ";}cout<<endl;*/if(m!=j){while(m<j){cs[m].count++;m++;}}hitnum++;// continue;}}}else//Cache块满了{m=0;max=0;location=0;while(m<bottom && cs[m].blocknum!=stream[i]) {cs[m].count++;if(cs[m].count>max){location=m;max=cs[m].count;}m++;}if(m==bottom)//未命中,所有块计数器都已加1,{result[bottom][i]=cs[location].blocknum;/*cout<<stream[i]<<"\t\t";cout<<"替换块"<<cs[location].blocknum<<"\t\t"; cout<<"未命中\t\t";*/cs[location].blocknum=stream[i];cs[location].count=0;result[location][i]=stream[i]; /* for(int t=0;t<bottom;t++) {if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' '; elsecout<<"空 ";}cout<<endl;*/}else//命中,{result[bottom+1][i]=0;/*cout<<stream[i]<<"\t\t"; cout<<"无替换\t\t";cout<<"命中\t\t";*/cs[m].count=0;m++;if(m!=bottom){while(m!=bottom){cs[m].count++;m++;}}/*for(int t=0;t<bottom;t++) {if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' '; elsecout<<"空 ";}cout<<endl;*/hitnum++;}}if(i<k-1){for(int r=0;r<bottom;r++) result[r][i+1]=result[r][i]; }}cout<<"块地址流 ";for(int t=0;t<k;t++)cout<<stream[t]<<"\t";cout<<endl<<"\t";for(t=0;t<(bottom+2);t++){cout<<endl<<"\t";for(int s=0;s<k;s++){if(t<bottom){if(result[t][s]==-1)cout<<"空\t";elsecout<<result[t][s]<<"\t";}else if(t==bottom){if(result[t][s]!=-1)//块替换cout<<"替换块"<<result[t][s]<<"\t"; else{if(result[t+1][s]!=-1)//块命中cout<<"无替换\t";elsecout<<"块失效\t";}}else{if(result[t][s]!=-1)//命中cout<<"命中\t";elsecout<<"未命中\t";}}cout<<endl;}cout<<endl;if(hitnum!=0){cout<<"采用全相联地址映射方式访问Cache的命中率为:"<<hitnum<<'/'<<k<<endl;}else{cout<<"采用全相联地址映射方式访问Cache的命中率为:0"<<endl;}}void Direct_link(CacheStruct cs[],int bottom,int stream[],int k,int result[20][20]){// cout<<"主存访问块流"<<" "<<"是否替换"<<" "<<"是否命中"<<" "<<"Cache块存放情况"<<endl;int location=-1,hitnum=0,m=0;for(int i=0;i<k;i++){location=stream[i]%bottom;if(cs[location].blocknum!=-1)//若产生冲突{if(cs[location].blocknum==stream[i])//若命中{result[bottom+1][i]=0;/*cout<<stream[i]<<"\t\t";cout<<"无替换\t\t";cout<<"命中\t\t";for(int t=0;t<bottom;t++){if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/hitnum++;//continue;}else{result[bottom][i]=cs[location].blocknum;/* cout<<stream[i]<<"\t\t";cout<<"替换块"<<cs[location].blocknum<<"\t\t"; cout<<"未命中\t\t";*/cs[location].blocknum=stream[i];result[location][i]=stream[i];// cs[location].count=0;/*for(int t=0;t<bottom;t++){if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/}}else//不产生冲突,仅是页面失效{cs[location].blocknum=stream[i]; result[location][i]=stream[i]; /* cout<<stream[i]<<"\t\t";cout<<"块失效\t\t";cout<<"未命中\t\t";for(int t=0;t<bottom;t++){if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/}if(i<k-1){for(int r=0;r<bottom;r++)result[r][i+1]=result[r][i];}}cout<<"块地址流 ";for(int t=0;t<k;t++)cout<<stream[t]<<"\t";cout<<endl<<"\t";for(t=0;t<(bottom+2);t++){cout<<endl<<"\t";for(int s=0;s<k;s++){if(t<bottom){if(result[t][s]==-1)cout<<"空\t";elsecout<<result[t][s]<<"\t";}else if(t==bottom){if(result[t][s]!=-1)//块替换cout<<"替换块"<<result[t][s]<<"\t"; else{if(result[t+1][s]!=-1)//块命中cout<<"无替换\t";elsecout<<"块失效\t";}}else{if(result[t][s]!=-1)//命中cout<<"命中\t";elsecout<<"未命中\t";}}cout<<endl;}cout<<endl;if(hitnum!=0){cout<<"采用直接地址映射方式访问Cache的命中率为:"<<hitnum<<'/'<<k<<endl;}else{cout<<"采用直接地址映射方式访问Cache的命中率为:0"<<endl;}}void Group_link(CacheStruct cs[],int bottom,int stream[],int k,int Gblock,int result[20][20]){// cout<<"主存访问块流"<<" "<<"是否替换"<<" "<<"是否命中"<<" "<<"Cache块存放情况"<<endl;int Cgroupnum=bottom/Gblock,Mgroupnum=0,location=-1;int start=-1,end=-1,max=0,m=-1,find=0,hitnum=0;for(int i=0;i<k;i++){Mgroupnum=stream[i]/Gblock;location=Mgroupnum%Cgroupnum;start=location*Gblock;end=start+Gblock-1;location=-1;find=0;m=-1;max=0;//以下实现组内全相联for(int j=start;j<=end;j++){if(find==0 && cs[j].blocknum==-1){location=j;find=1;}if(cs[j].blocknum!=-1)cs[j].count++;if(cs[j].count>max){max=cs[j].count;m=j;}if(cs[j].blocknum==stream[i]) break;}if(j<=end)//命中{result[bottom+1][i]=0;/*cout<<stream[i]<<"\t\t"; cout<<"无替换\t\t";cout<<"命中\t\t";*/cs[j].count=0;if(j<end){j++;while(j<=end){if(cs[j].blocknum!=-1)cs[j].count++;j++;}}/* for(int t=0;t<bottom;t++) {if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/hitnum++;}else//未命中{if(location!=-1)//Cache有空余块{result[location][i]=stream[i]; /*cout<<stream[i]<<"\t\t";cout<<"块失效\t\t";cout<<"未命中\t\t";*/cs[location].blocknum=stream[i]; cs[location].count=0;/*for(int t=0;t<bottom;t++){if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/}else//替换{result[bottom][i]=cs[m].blocknum;/* cout<<stream[i]<<"\t\t";cout<<"替换块"<<cs[m].blocknum<<"\t\t"; cout<<"未命中\t\t";*/cs[m].blocknum=stream[i];cs[m].count=0;result[m][i]=stream[i];/* for(int t=0;t<bottom;t++){if(cs[t].blocknum!=-1)cout<<cs[t].blocknum<<' ';elsecout<<"空 ";}cout<<endl;*/}}if(i<k-1){for(int r=0;r<bottom;r++) result[r][i+1]=result[r][i]; }}cout<<"块地址流 ";for(int t=0;t<k;t++)cout<<stream[t]<<"\t";cout<<endl<<"\t";for(t=0;t<(bottom+2);t++) {cout<<endl<<"\t";for(int s=0;s<k;s++){if(t<bottom){if(result[t][s]==-1)cout<<"空\t";elsecout<<result[t][s]<<"\t";}else if(t==bottom){if(result[t][s]!=-1)//块替换cout<<"替换块"<<result[t][s]<<"\t"; else{if(result[t+1][s]!=-1)//块命中cout<<"无替换\t";elsecout<<"块失效\t";}}else{if(result[t][s]!=-1)//命中cout<<"命中\t";elsecout<<"未命中\t";}}cout<<endl;}cout<<endl;if(hitnum!=0){cout<<"采用组相联地址映射方式访问Cache的命中率为:"<<hitnum<<'/'<<k<<endl;}else{cout<<"采用组相联地址映射方式访问Cache的命中率为:0"<<endl;}}void main(){CacheStruct cs[100];int result[20][20];int stream[100];intCvolumn=0,Mvolumn=0,Blockvolumn=0,Mblocknum=0,Cblocknum=0,groupnum=0 ,k=0,type=-1,t=-1;char ch='y';while(ch=='y'||ch=='Y'){system("cls");k=0;type=-1;t=-1;for(int i=0;i<100;i++){cs[i].blocknum=-1;cs[i].count=0;}cout<<"请依次输入主存空间大小(MB),Cache空间大小(KB),分块大小(KB):"; cin>>Mvolumn>>Cvolumn>>Blockvolumn;/*问题改进:1.界面输入输出方式2.容量之间的关系3.*/while((Mvolumn*1024)%Blockvolumn!=0 || Cvolumn%Blockvolumn!=0){cout<<"主存空间大小与Cache空间大小应是块大小的整数倍~";cout<<"请依次输入主存空间大小(MB),Cache空间大小(KB),分块大小(KB):"; cin>>Mvolumn>>Cvolumn>>Blockvolumn;}Mblocknum=(Mvolumn*1024)/Blockvolumn;Cblocknum=Cvolumn/Blockvolumn;cout<<"请输入CPU访问主存块流:(-1结束输入)";cin>>t;while(t!=-1){if(t<0 || t>=Mblocknum){/* cout<<"输入的主存块地址号有误~请重新输入:";cin>>t;while(t<0 || t>=Mblocknum ||t==-1){if(t==-1)break;else{cout<<"输入的主存块地址号有误~请重新输入:"; cin>>t;}}if(t!=-1){stream[k]=t;k++;cin>>t;}*/cout<<"已跳过输入错误的无效的块地址~"; cin>>t;}else{stream[k]=t;k++;cin>>t;}}//完成result数组的初始化for(i=0;i<20;i++){for(int j=0;j<20;j++){result[i][j]=-1;}}cout<<"请输入地址映射方式:(1.全相联 2.直接映射 3.组相联)";cin>>type;switch(type){case 1:All_LinkLRU(cs,Cblocknum,stream,k,result);break;case 2:Direct_link(cs,Cblocknum,stream,k,result);break;case 3:{cout<<"请输入主存分组数:";cin>>groupnum;while(Mblocknum%groupnum!=0 || Cblocknum%(Mblocknum/groupnum)!=0)//输入的组数不能被整除{cout<<"输入主存分组数有误~请依据主存与Cache分块数确定合适的分组数:";cin>>groupnum;}Group_link(cs,Cblocknum,stream,k,Mblocknum/groupnum,result);}}cout<<"还要继续输入块地址流吗,(Y or N)";cin>>ch;}// All_LinkLRU(cs,Cblocknum,stream,k);//Direct_link(cs,Cblocknum,stream,k);/* cout<<"请输入主存分组数:";cin>>groupnum;Group_link(cs,Cblocknum,stream,k,Mblocknum/groupnum);}四、实验截图采用全相联映射方式:采用组相联映射方式:采用直接相联映射方式:五、实验总结通过上机操作,我掌握了常用的几种存储地址映象与变换方法即全相联映象方式,直接映象方式和组相联映象方式,并且认识了虚拟存贮层次结构,而且了解了FIFO、LRU等替换算法的工作全过程。

相关主题