1、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、再取出两个最小的概率节点相
2、加,生成一个生的节点加入到链表中,同时从两表中删除此两个节点。3、在对链表进行排序,链表是否只有一个节点,是则HUFFAN树构造完毕,否则继续做2的操作。为此设计一个工作链表(链表的元素时类,此类的功能相当结构。)、HUFFMAN树节点、HUFFMAN编码表节点。具体如下: /huff_man tree point; class huff_p public: huff_p* r_child; /大概率的节点,即右子节点; huff_p* l_child; /小概率的节点,即左子节点; char op_mask3; /指令标号;float p; /指令使用概率; ; /work link poi
3、nt class f_min_p public: f_min_p* next; float p; huff_p* huf_p; /huff_man code point class huff_code public: huff_code* next; char codeN; /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); /在工作链表中寻找最小概率节点函数
4、。 f_min_p* del_min(f_min_p* h,f_min_p* p);/在工作链表中删除最小概率节点函数。 void insert_n(f_min_p* h,f_min_p* p);/ 在工作链表中插入两个最小概率节点生成的节点函数。 huff_p* creat_huffp(f_min_p* p);/生成HUFFMAN节点。void creat_huffman_code(huff_p* h1,huff_code* h);/生成huffman编码; void r_find(huff_p* p1,char code,int i,huff_code* h); /遍历HUFFMAN树生成
5、指令操作码的HUFFMAN编码。 void output_huffman(huff_code* head);/输出huffman编码; void cal_sort_length(huff_code* head);/计算指令用huffman编码的平均编码字长三、程序清单#includemath.h#defineN8/findtwominprogram;/huff_mantreepont;classhuff_ppublic:huff_p*r_child;/大概率的节点;l_child;/小概率的节点;charop_mask3;/指令标号;floatp;/指令使用概率;;f_min_pf_min_p
6、*next;huf_p;codehuff_codehuff_code*codeN;/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);voidinsert_n(f_min_p*creat_huffp(f_min_p*creat_huffman_code(huff_p*h1,huff_code*r_find(huff_p*p1,charcode,inti,huff_code*output_huffman(huff_code*
7、void cal_sort_length(huff_code* head);/计算指令用huffman编码的平均编码字长 void main() f_min_p *h,*h1; huff_p *root; huff_code* head,*pl; int i=0; h=input_instruct_set(); /* p1=h; while(p1) coutp */ h1=h; root=creat_huffman_tree(h1); head=new huff_code; head-next=NULL; creat_huffman_code(root,head); output_huffma
8、n(head); cal_sort_length(head); pl=head- while(pl) delete head; head=pl; pl=pl- f_min_p* input_instruct_set() f_min_p* head; f_min_p* h; h=new f_min_p; h-huf_p=NULL; head=h; int n; coutn;请输入指令标号:h-op_mask;请输入指令的使用概率: f_min_p* point; f_min_p* p1=head; for(;i point-op_mask2=0next=p1- p1-next=point; p1
9、=point; return head; 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); else min2=h1; rd=creat_huffp(min2); comb=new f_min_p; comb-p=rd-p+ld-op_mask0=op_m
10、ask1= 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); els
11、e rd=min2- comb=new f_min_p; if(h1!=NULL) insert_n(h1,comb);+i h1=h1- while(h1) if(min(h1-p) min=h1- h1=h1- return p1; 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- delete p; else while(p1-=NULL) p1=p1- if(p1=p) p2- break; p2=p1; return h; void insert_n(f_min_p *
12、h,f_min_p *p1) p1-next=h-next=p1; huff_p* creat_huffp(f_min_p* d) huff_p* p1; p1=new huff_p;l_child=NULL;r_child=NULL;p=d-op_mask0=d-op_mask0;op_mask1=d-op_mask1; return p1; void r_find(huff_p* p1,char code,int i,huff_code* h) if(p1-l_child) codei=1 r_find(p1-l_child,code,i+1,h); if(p1-op_mask0!=) h
13、uff_code* p2=new huff_code; p2-op_mask0=p1-op_mask1=p1-p=p1- int j; for( j=0;jcodej=codej; p2-codej=next=p2;r_child) codei=0r_child,code,i+1,h); delete p1; void creat_huffman_code(huff_p* h1,huff_code* h) int i=0; r_find(h1,code,i,h); void output_huffman(huff_code* head) huff_code* h=head-OP:-概率- -编
14、码- while(h) h-op_mask: code cout double j=0; float one_length=0; float per_length=0; float ext_length=0;/按1-2-3-5扩展编码的最小长度为。 while(h) float length=0; while(h-codei!) length+; i+; one_length=h-p*length; per_length=per_length+one_length; j+; int i1=int(j); huff_code *p2=head- float* p_a=new floati1; /
15、sort指令概率 int i0=0; while(p2) p_ai0+=p2- p2=p2- float max,temp; int l; for(int s=0;si1;s+) max=p_as; l=s; for(int k=s+1;kk+) if(maxp_ak) max=p_ak;l=k; temp=p_as; p_as=max; p_al=temp; /计算1-2-3-5扩展编码的最短平均长度 float* code_len=new floati1; code_len0=1; code_len1=2; code_len2=3; code_len3=5; for(int i=4;j;i
16、+)code_leni=5; l=0; while(li1) ext_length=ext_length+code_lenl*p_al; l+; /计算等长编码平均长度;double q_length=log10(j)/log10(2);此指令集操作码huffman编码的平均长度为:per_length等长编码的平均长度为:q_lengthper_length) cout可见HUFFMAN编码的平均长度要比等长编码的平均长度短 else cout可见HUFFMAN编码的平均长度要比1-2-3-5扩展编码的最短平均长度短 四、结果分析由上面的输出结果界面可以看到程序输出霍夫曼编码及扩展编码的结果
17、,输出的结果对照理论得到的结果完全一样。证明该程序的实现是正确的。五、调试报告对此实验的调试刚开始出现了一个错误经过分析,是忘记了输出huffman编码的函数所以在38行加上了 void output_huffman(huff_code* head);实验 2 使用 LRU 方法更新 Cache清楚认识虚拟存贮层次结构,熟练掌握常用的几种存储地址映象与变换方法,以及FIFO、LRU等替换算法的工作全过程。 要求用程序实现任意地址流在存储层次上的命中情况,实验结束后提交源程序和实验说明书。二、 问题简要描述在模拟器上实现在任意地址流下求出在cache 主存辅存三层存贮层次上的命中率。1Cache
18、主存:映像方式可以选择全相联、直接映象、组相联方式;替换 算法一般使用LRU算法。2.主存辅存:映像方式采用组相联,替换算法分别选择FIFO、LRU两种算法实现。3要求Cache大小、主存容量、块大小、页大小以及组数等可以输入修改。4求出命中率;显示替换的全过程;任选一种高级语言来做。5要有简洁、易于操作的界面。利用教材和实验要求提供的各种算法实现对存储系统的模拟。主要本程 序主要做了一下工作:(1) 构造存储器的类(CMemStruct),实现对cache,主存,辅存的结果的模拟;(2) 在类中封装各种函数,如调度函数,印象选择函数等来实现对存储器的 操作;(3) 在主对话框上利用CList
19、Ctrl控件实现调度的显示。 在对存储的结构设计上,采用了二维的数组来实现其中第一维对应的是存储器的页(或cache的块大小),二维数组的大小代表的存储器的总容量。 在对映像方式的设计时,根据数组的下表来完成。例如:主存辅存组相连映像根据数据所在的辅存页编号除以主存中的组内字节数再对主存组数取余几个得到对应主存中的组号。 在对替换算法的设计上,采用计数机的方式实现。LRU替换算法,每次对操作的页(块)计数器清0,对其他的页(块)加1。当替换时选择计数最大值页(块)替换。在访存操作上,采用根据数据查询对应的数据所在的页(或块)。再来决定作操作(命中,替换,调进)。访存的顺序应该为cache主存辅
20、存,当内容在辅存中时要先将辅存中的内容先调入主存,再由主存调入cache。但是由于主存和辅存是页对应的关系而cache和主存是块的对应关系所以在替换上是要采用地址变换的方法。本程序为的实现的方便采用连个存储器来解决问题,用这两个大小相等的存储器来分别和cache,辅存对应,一个采用块数量来做二维数组一维大小,另一个采用页数量来做二维数组一维大小,这样当主存调入或替换时将两个数组的内容负责以下就可以实现,免去了地址的复杂变换。三、程序主要代码存储器类 (1) 类声明:class CMemStruct public: CMemStruct(void);CMemStruct(void); int m
21、_nPieceNums; /块或页数量 int m_nPieceBytes; /块或页内字节数 int m_nGroupNums;/组数 int m_nNowPieceNum; /当前块号 或 页号 int m_nNowPieceByte; /当前块内 或 页内编号 int m_nNowGroupNum;/当前组数 int m_nFalgChange; /替换算法,为0-FIFO;为1-LRU int* m_nNumLCount;/LRU计数器 int* m_nNumFCount;/FIFO计数器 int m_nFalgMap; /映像关系,为0-全相连;为1-直接相连;为2-组相连 CStr
22、ing* m_strInfo; /单元内容 BOOL IsFind(CString strInfo);void Change(CString* strInfo, int nPieceNum, int nPieceByte);void ScarchForChangeLRU(int nStart,int nEnd); / 调进函数 BOOL IsInsert(CString* strInfo, int nPieceNum , int nPieceByte); void InitInfo(); void InsertInfo(CString* strInfo);(2) 各函数的实现:CMemStruct:CMemStruct(void) this-m_nFalgChange = 1;/LRU this-m_nFalgMap = 0;/全相连 this-m_nPieceNums = 0;m_nPieceBytes = 0;m_nNowPieceByte = 0;m_nNowPieceNum =
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1