计算机体系结构实验报告Word文档下载推荐.docx
- 文档编号:19534760
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:14
- 大小:83.76KB
计算机体系结构实验报告Word文档下载推荐.docx
《计算机体系结构实验报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《计算机体系结构实验报告Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。
3
4
5
6
最短编码长度为:
H=0.45*1+0.30*2+0.15*3+0.05*4+0.03*5+0.01*6+0.01*6=-1.95.
要对指令的操作码进行HUFFMAN编码,只要根据指令的各类操作码的出现概率构造HUFFMAN树再进行HUFFAM编码。
此过程的难点构造HUFFMAN树,进行HUFFAM编码只要对你所生成的HUFFMAN树进行中序遍历即可完成编码工作。
再采用固定长操作码与霍夫曼编码相结合的方法得到扩展编码。
二、设计简要描述
观察上图1,不难看出构造HUFFMAN树所要做的工作:
1、先对各指令操作码的出现概率进行排序,构造一个有序链表。
2、再取出两个最小的概率节点相加,生成一个生的节点加入到链表中,同时从两表中删除此两个节点。
3、在对链表进行排序,链表是否只有一个节点,是则HUFFAN树构造完毕,否则继续做2的操作。
为此设计一个工作链表(链表的元素时类,此类的功能相当结构。
)、HUFFMAN树节点、HUFFMAN编码表节点。
具体如下:
//huff_mantreepoint;
classhuff_p{public:
huff_p*r_child;
//大概率的节点,即右子节点;
huff_p*l_child;
//小概率的节点,即左子节点;
charop_mask[3];
//指令标号;
floatp;
//指令使用概率;
};
//worklinkpointclassf_min_p{public:
f_min_p*next;
floatp;
huff_p*huf_p;
/huff_mancodepointclasshuff_code{public:
huff_code*next;
charcode[N];
//huffman编码;
函数说明:
f_min_p*input_instruct_set();
//输入指令集子模块;
huff_p*creat_huffman_tree(f_min_p*head);
//构造huffman树;
f_min_p*fin_min(f_min_p*h);
//在工作链表中寻找最小概率节点函数。
f_min_p*del_min(f_min_p*h,f_min_p*p);
//在工作链表中删除最小概率节点函数。
voidinsert_n(f_min_p*h,f_min_p*p);
//在工作链表中插入两个最小概率节点生成的节点函数。
huff_p*creat_huffp(f_min_p*p);
//生成HUFFMAN节点。
voidcreat_huffman_code(huff_p*h1,huff_code*h);
//生成huffman编码;
voidr_find(huff_p*p1,charcode[],inti,huff_code*h);
//遍历HUFFMAN树生成指令操作码的HUFFMAN编码。
voidoutput_huffman(huff_code*head);
//输出huffman编码;
voidcal_sort_length(huff_code*head);
//计算指令用huffman编码的平均编码字长
三、程序清单
#include<
iostream.h>
math.h>
#define
N
8
//find
two
min
program;
//huff_man
tree
pont;
class
huff_p{
public:
huff_p*
r_child;
//大概率的节点;
l_child;
//小概率的节点;
char
op_mask[3];
//指令标号;
float
p;
//指令使用概率;
};
f_min_p{
f_min_p*
next;
huf_p;
code
huff_code{
huff_code*
code[N];
//huffman
编码;
input_instruct_set();
creat_huffman_tree(f_min_p*
head);
fin_min(f_min_p*
h);
del_min(f_min_p*
h,f_min_p*
p);
void
insert_n(f_min_p*
creat_huffp(f_min_p*
creat_huffman_code(huff_p*
h1,huff_code*
r_find(huff_p*
p1,char
code[],int
i,huff_code*
output_huffman(huff_code*
voidcal_sort_length(huff_code*head);
//计算指令用huffman编码的平均编码字长voidmain(){f_min_p*h,*h1;
huff_p*root;
huff_code*head,*pl;
inti=0;
h=input_instruct_set();
/*p1=h;
while(p1){cout<
<
p1->
p<
'
'
;
p1=p1->
}*/h1=h;
root=creat_huffman_tree(h1);
head=newhuff_code;
head->
next=NULL;
creat_huffman_code(root,head);
output_huffman(head);
cal_sort_length(head);
pl=head->
while(pl){deletehead;
head=pl;
pl=pl->
}}f_min_p*input_instruct_set(){f_min_p*head;
f_min_p*h;
h=newf_min_p;
h->
huf_p=NULL;
head=h;
intn;
cout<
"
请输入指令数:
cin>
>
n;
请输入指令标号:
h->
op_mask;
请输入指令的使用概率:
f_min_p*point;
f_min_p*p1=head;
for(;
i<
n-1;
i++){point=newf_min_p;
point->
point->
op_mask[2]='
\0'
next=p1->
p1->
next=point;
p1=point;
}returnhead;
}huff_p*creat_huffman_tree(f_min_p*h){f_min_p*h1,*min1,*min2,*comb;
huff_p*head,*rd,*ld,*parent;
h1=h;
min1=fin_min(h1);
ld=creat_huffp(min1);
h1=del_min(h1,min1);
if(h1->
next)min2=fin_min(h1);
elsemin2=h1;
rd=creat_huffp(min2);
comb=newf_min_p;
comb->
p=rd->
p+ld->
op_mask[0]='
op_mask[1]='
parent=creat_huffp(comb);
insert_n(h1,comb);
next!
=NULL)h1=del_min(h1,min2);
parent->
l_child=ld;
r_child=rd;
huf_p=parent;
head=parent;
endl;
while(h1->
=NULL){min1=fin_min(h1);
if(min1->
huf_p==NULL){ld=creat_huffp(min1);
}else{ld=min1->
}h1=del_min(h1,min1);
if(min2->
huf_p==NULL){rd=creat_huffp(min2);
}else{rd=min2->
}comb=newf_min_p;
if(h1!
=NULL)insert_n(h1,comb);
++i<
next==NULL)break;
}deletecomb;
returnhead;
}f_min_p*fin_min(f_min_p*h){f_min_p*h1,*p1;
p1=h1;
floatmin=h1->
h1=h1->
while(h1){if(min>
(h1->
p)){min=h1->
}h1=h1->
}returnp1;
}f_min_p*del_min(f_min_p*h,f_min_p*p){f_min_p*p1,*p2;
p1=h;
p2=h;
if(h==p){h=h->
deletep;
}else{while(p1->
=NULL){p1=p1->
if(p1==p){p2->
break;
}p2=p1;
}}returnh;
}voidinsert_n(f_min_p*h,f_min_p*p1){p1->
next=h->
next=p1;
}huff_p*creat_huffp(f_min_p*d){huff_p*p1;
p1=newhuff_p;
l_child=NULL;
r_child=NULL;
p=d->
op_mask[0]=d->
op_mask[0];
op_mask[1]=d->
op_mask[1];
returnp1;
}voidr_find(huff_p*p1,charcode[],inti,huff_code*h){if(p1->
l_child){code[i]='
1'
r_find(p1->
l_child,code,i+1,h);
}if(p1->
op_mask[0]!
='
){huff_code*p2=newhuff_code;
p2->
op_mask[0]=p1->
op_mask[1]=p1->
p=p1->
intj;
for(j=0;
j<
i;
j++){p2->
code[j]=code[j];
}p2->
code[j]='
next=p2;
r_child){code[i]='
0'
r_child,code,i+1,h);
}deletep1;
}voidcreat_huffman_code(huff_p*h1,huff_code*h){inti=0;
r_find(h1,code,i,h);
}voidoutput_huffman(huff_code*head){huff_code*h=head->
OP:
--概率--"
'
--编码--"
---------------------------------"
while(h){h->
op_mask<
:
"
code<
h=h->
}cout<
}voidcal_sort_length(huff_code*head){huff_code*h=head->
doublej=0;
floatone_length=0;
floatper_length=0;
floatext_length=0;
//按1-2-3-5扩展编码的最小长度为。
while(h){floatlength=0;
while(h->
code[i]!
){length++;
i++;
}one_length=h->
p*length;
per_length=per_length+one_length;
j++;
}inti1=int(j);
huff_code*p2=head->
float*p_a=newfloat[i1];
//sort指令概率inti0=0;
while(p2){p_a[i0++]=p2->
p2=p2->
}floatmax,temp;
intl;
for(ints=0;
s<
i1;
s++){max=p_a[s];
l=s;
for(intk=s+1;
k<
k++){if(max<
p_a[k]){max=p_a[k];
l=k;
}}temp=p_a[s];
p_a[s]=max;
p_a[l]=temp;
}//计算1-2-3-5扩展编码的最短平均长度float*code_len=newfloat[i1];
code_len[0]=1;
code_len[1]=2;
code_len[2]=3;
code_len[3]=5;
for(inti=4;
j;
i++)code_len[i]=5;
l=0;
while(l<
i1){ext_length=ext_length+code_len[l]*p_a[l];
l++;
}//计算等长编码平均长度;
doubleq_length=log10(j)/log10
(2);
此指令集操作码huffman编码的平均长度为:
per_length<
等长编码的平均长度为:
q_length<
按1-2-3-5的扩展编码的最短平均编码长度为:
ext_length;
if(q_length>
per_length){cout<
可见HUFFMAN编码的平均长度要比等长编码的平均长度短"
}else{cout<
huffman编码有问题请仔细查看算法,以及输入的指令集的概率之和是否大于1。
}if(ext_length>
可见HUFFMAN编码的平均长度要比1-2-3-5扩展编码的最短平均长度短"
}}
四、结果分析
由上面的输出结果界面可以看到程序输出霍夫曼编码及扩展编码的结果,输出的结果对照理论得到的结果完全一样。
证明该程序的实现是正确的。
五、调试报告
对此实验的调试刚开始出现了一个错误
经过分析,是忘记了输出huffman编码的函数
所以在38行加上了voidoutput_huffman(huff_code*head);
实验2使用LRU方法更新Cache
清楚认识虚拟存贮层次结构,熟练掌握常用的几种存储地址映象与变换方法,以及FIFO、LRU等替换算法的工作全过程。
要求用程序实现任意地址流在存储层次上的命中情况,实验结束后提交源程序和实验说明书。
二、问题简要描述
在模拟器上实现在任意地址流下求出在cache—主存—辅存三层存贮层次上的命中率。
1.Cache—主存:
映像方式可以选择全相联、直接映象、组相联方式;
替换算法一般使用LRU算法。
2.主存—辅存:
映像方式采用组相联,替换算法分别选择FIFO、LRU两种算法实现。
3.要求Cache大小、主存容量、块大小、页大小以及组数等可以输入修改。
4.求出命中率;
显示替换的全过程;
任选一种高级语言来做。
5.要有简洁、易于操作的界面。
利用教材和实验要求提供的各种算法实现对存储系统的模拟。
主要本程序主要做了一下工作:
(1)构造存储器的类(CMemStruct),实现对cache,主存,辅存的结果的模拟;
(2)在类中封装各种函数,如调度函数,印象选择函数等来实现对存储器的操作;
(3)在主对话框上利用CListCtrl控件实现调度的显示。
在对存储的结构设计上,采用了二维的数组来实现其中第一维对应的是存储器的页(或cache的块大小),二维数组的大小代表的存储器的总容量。
在对映像方式的设计时,根据数组的下表来完成。
例如:
主存—辅存组相连映像根据数据所在的辅存页编号除以主存中的组内字节数再对主存组数取余几个得到对应主存中的组号。
在对替换算法的设计上,采用计数机的方式实现。
LRU替换算法,每次对操作的页(块)计数器清0,对其他的页(块)加1。
当替换时选择计数最大值页(块)替换。
在访存操作上,采用根据数据查询对应的数据所在的页(或块)。
再来决定作操作(命中,替换,调进)。
访存的顺序应该为cache—主存—辅存,当内容在辅存中时要先将辅存中的内容先调入主存,再由主存调入cache。
但是由于主存和辅存是页对应的关系而cache和主存是块的对应关系所以在替换上是要采用地址变换的方法。
本程序为的实现的方便采用连个存储器来解决问题,用这两个大小相等的存储器来分别和cache,辅存对应,一个采用块数量来做二维数组一维大小,另一个采用页数量来做二维数组一维大小,这样当主存调入或替换时将两个数组的内容负责以下就可以实现,免去了地址的复杂变换。
三、程序主要代码
存储器类
(1)类声明:
classCMemStruct
{public:
CMemStruct(void);
~CMemStruct(void);
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;
//单元内容
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;
//LRUthis->
m_nFalgMap=0;
////全相连
this->
m_nPieceNums=0;
m_nPieceBytes=0;
m_nNowPieceByte=0;
m_nNowPieceNum=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机体系结构 实验 报告