计算机体系结构实验报告1.docx
《计算机体系结构实验报告1.docx》由会员分享,可在线阅读,更多相关《计算机体系结构实验报告1.docx(13页珍藏版)》请在冰点文库上搜索。
计算机体系结构实验报告1
计算机系统结构课程
实验报告
实验名称:
存贮层次模拟器
姓名:
田莉莉
学号:
专业:
计算机科学与技术
指导教师:
孙全红
教研室:
计算机系统结构教研室
2012年10月19日
一、实验目的与要求
使学生清楚认识虚拟存贮层次结构,熟练掌握常用的几种存储地址映象与变换方法,以及FIFO、LRU等替换算法的工作全过程。
要求用程序实现任意地址流在存储层次上的命中情况,实验结束后提交源程序和实验说明书。
二、实验内容
在模拟器上实现在任意地址流下求出在cache—主存—辅存三层存贮层次上的命中率。
三、实验步骤
1.Cache—主存:
映像方式可以选择全相联、直接映象、组相联方式;替换算法一般使用LRU算法。
2.主存—辅存:
映像方式采用组相联,替换算法分别选择FIFO、LRU两种算法实现。
3.要求Cache大小、主存容量、块大小、页大小以及组数等可以输入修改。
4.求出命中率;显示替换的全过程;任选一种高级语言来做。
5.要有简洁、易于操作的界面。
四、实验步骤
1、设计思想:
利用教材和实验要求提供的各种算法实现对存储系统的模拟。
主要本程序主要做了一下工作:
(1)构造存储器的类(CMemStruct),实现对cache,主存,辅存的结果的模拟;
(2)在类中封装各种函数,如调度函数,印象选择函数等来实现对存储器的操作;
(3)在主对话框上利用CListCtrl控件实现调度的显示。
在对存储的结构设计上,采用了二维的数组来实现其中第一维对应的是存储器的页(或cache的块大小),二维数组的大小代表的存储器的总容量。
在对映像方式的设计时,根据数组的下表来完成。
例如:
主存—辅存组相连映像根据数据所在的辅存页编号除以主存中的组内字节数再对主存组数取余几个得到对应主存中的组号。
在对替换算法的设计上,采用计数机的方式实现。
例如:
LRU替换算法,每次对操作的页(块)计数器清0,对其他的页(块)加1。
当替换时选择计数最大值页(块)替换。
在访存操作上,采用根据数据查询对应的数据所在的页(或块)。
再来决定作操作(命中,替换,调进)。
访存的顺序应该为cache—主存—辅存,当内容在辅存中时要先将辅存中的内容先调入主存,再由主存调入cache。
但是由于主存和辅存是页对应的关系而cache和主存是块的对应关系所以在替换上是要采用地址变换的方法。
本程序为的实现的方便采用连个存储器来解决问题,用这两个大小相等的存储器来分别和cache,辅存对应,一个采用块数量来做二维数组一维大小,另一个采用页数量来做二维数组一维大小,这样当主存调入或替换时将两个数组的内容负责以下就可以实现,免去了地址的复杂变换。
2、程序主要代码
存储器类
(1)类声明:
classCMemStruct
{
public:
CMemStruct(void);
~CMemStruct(void);
public:
intm_nPieceNums;//块或页数量
intm_nPieceBytes;//块或页内字节数
intm_nGroupNums;//组数
intm_nNowPieceNum;//当前块号或页号
intm_nNowPieceByte;//当前块内或页内编号
intm_nNowGroupNum;//当前组数
intm_nFalgChange;//替换算法,为0--->FIFO;为1--->LRU
int*m_nNumLCount;//LRU计数器
int*m_nNumFCount;//FIFO计数器
intm_nFalgMap;//映像关系,为0-->全相连;为1-->直接相连;为2-->组相连
CString**m_strInfo;//单元内容
public:
BOOLIsFind(CStringstrInfo);
voidChange(CString*strInfo,intnPieceNum,intnPieceByte);
voidScarchForChangeLRU(intnStart,intnEnd);
//调进函数
BOOLIsInsert(CString*strInfo,intnPieceNum,intnPieceByte);
voidInitInfo();
voidInsertInfo(CString*strInfo);
};
(2)各函数的实现:
CMemStruct:
:
CMemStruct(void)
{
this->m_nFalgChange=1;//LRU
this->m_nFalgMap=0;////全相连
this->m_nPieceNums=0;
this->m_nPieceBytes=0;
this->m_nNowPieceByte=0;
this->m_nNowPieceNum=0;
this->m_strInfo=NULL;
}
CMemStruct:
:
~CMemStruct(void)
{
}
BOOLCMemStruct:
:
IsFind(CStringstrInfo)//判断是否命中
{
for(inti=0;ifor(intj=0;j{
if(m_strInfo[i][j]==strInfo)
{
m_nNowPieceNum=i;
m_nNowPieceByte=j;
if(m_nFalgChange==0)//更新计数器值
{
for(inti=0;i{
if(*m_strInfo[i]!
=_T(""))
m_nNumFCount[i]++;
}
}
elseif(m_nFalgChange==1)
{
for(inti=0;i{
if(m_strInfo[i][0]!
=_T(""))
m_nNumLCount[i]++;
}
m_nNumLCount[m_nNowPieceNum]=0;
}
return1;
}
}
return0;
}
voidCMemStruct:
:
Change(CString*strInfo,intnPieceNum,intnPieceByte)//替换函数
{
switch(m_nFalgMap)
{
case0:
//全相连
{
this->ScarchForChangeLRU(0,m_nPieceNums);
for(inti=0;i{
if(m_strInfo[i][0]!
=_T(""))
m_nNumLCount[i]++;
}
for(inti=0;i{
m_strInfo[m_nNowPieceNum][i]=strInfo[i];
}
m_nNumLCount[m_nNowPieceNum]=0;
}
break;
case1:
//直接相连
{
m_nNowPieceNum=nPieceNum%m_nPieceNums;
for(inti=0;i{
m_strInfo[m_nNowPieceNum][i]=strInfo[i];
}
}
break;
case2:
{
intnCount=(m_nPieceNums/m_nGroupNums);//组内块数
m_nNowGroupNum=(nPieceNum/nCount)%m_nGroupNums;//得到组号
intnStart=m_nNowGroupNum*nCount;
intnEnd=nStart+nCount;
if(m_nFalgChange==0)//FIFO
{
//查找FIFO中要替换的页面
intn=m_nNumFCount[0];
for(inti=nStart;i{
if(n{
n=m_nNumFCount[i];
m_nNowPieceNum=i;
}
}
m_nNumFCount[m_nNowPieceNum]=0;
//
for(inti=0;i{
if(m_strInfo[i][0]!
=_T(""))
m_nNumLCount[i]++;
}
for(inti=0;i{
m_strInfo[m_nNowPieceNum][i]=strInfo[i];
}
}
elseif(m_nFalgChange==1)//LRU
{
this->ScarchForChangeLRU(nStart,nEnd);
for(inti=0;i{
if(m_strInfo[i][0]!
=_T(""))
m_nNumLCount[i]++;
}
for(inti=0;i{
m_strInfo[m_nNowPieceNum][i]=strInfo[i];
}
m_nNumLCount[m_nNowPieceNum]=0;
}
}
break;
}
}
voidCMemStruct:
:
ScarchForChangeLRU(intnStart,intnEnd)
{
intn=m_nNumLCount[0];
m_nNowPieceNum=0;
for(inti=nStart;i{
if(n{
n=m_nNumLCount[i];
m_nNowPieceNum=i;
}
}
}
//调进函数
BOOLCMemStruct:
:
IsInsert(CString*strInfo,intnPieceNum,intnPieceByte)//判断是否调进函数
{
switch(m_nFalgMap)
{
case0:
//全相连
{
for(inti=0;i{
if(m_strInfo[i][0]!
=_T(""))
m_nNumLCount[i]++;
if(m_strInfo[i][0]==_T(""))
{
m_nNumLCount[i]=0;
m_nNowPieceNum=i;
return1;
}
}
}
break;
case1:
//直接相连
{
m_nNowPieceNum=nPieceNum%m_nPieceNums;
if(m_strInfo[m_nNowPieceNum][0]==_T(""))
{
return1;
}
}
break;
case2:
{
intnCount=(m_nPieceNums/m_nGroupNums);//组内块数
m_nNowGroupNum=(nPieceNum/nCount)%m_nGroupNums;//得到组号
intnStart=m_nNowGroupNum*nCount;
intnEnd=nStart+nCount;
for(inti=nStart;i{
if(m_strInfo[i][0]!
=_T(""))
{
m_nNumLCount[i]++;
m_nNumFCount[i]++;
}
if(*m_strInfo[i]==_T(""))
{
m_nNumFCount[i]=0;
m_nNumLCount[i]=0;
m_nNowPieceNum=i;
return1;
}
}
}
break;
}
return0;
}
voidCMemStruct:
:
InitInfo()
{
m_strInfo=newCString*[m_nPieceNums];
for(inti=0;i{
m_strInfo[i]=newCString[m_nPieceBytes];
}
m_nNumLCount=newint[m_nPieceNums];
m_nNumFCount=newint[m_nPieceNums];
for(inti=0;i{
for(intj=0;j{
m_strInfo[i][j]=_T("");
}
m_nNumLCount[i]=0;
m_nNumFCount[i]=0;
}
}
voidCMemStruct:
:
InsertInfo(CString*strInfo)
{
for(inti=0;i{
m_strInfo[m_nNowPieceNum][i]=strInfo[i];
}
}
3、程序运行结果
程序的运行结果如图1.1所示:
图1.1程序运行结果
四、实验心得
本次实验我加深了对存储系统的理解,但在程序的设计中还存在一些问题:
(1)存储器类的实现:
本实验我使用了同一个类来描述cache、主存和辅存。
但是他们都有各自的特点,若采用同一个基类派生的话效果会更好;
(2)地址流是在程序内封装的,不能手动输入,在这一块不太灵活;
(3)在代码的优化上还有很多的工作要做;
虽然本实验的主要功能实现了,但是在很多细节方面还没有完善需要以后继续处理。