【体系结构】转移预测器设计与比较

转自:http://blog.csdn.net/xiaowei_cqu/article/details/9455515

【体系结构】转移预测器设计与比较

分类: 【C/C++】   333人阅读  评论(1)  收藏  举报

目录(?)[+]

关联预测器

一个[m,n]预测器表示使用前m个分支行为去从2^m个分支预测中进行选择,每一个预测是对应于单个分支的n位预测器。这种相关分支预测器的吸引人之处,即在于它与两位预测器相比可以取得更高的预测率,并且只需要少量的额外硬件支持。其硬件的简单性表现在:最近m个分支的全局历史记录可以记录在一个m位移位寄存器中,每一位记录着该分支是被执行还是未被执行。对分支预测缓冲站的访问可由分支地址的低位拼接上m位全局历史记录而得到。以下是一个[2,2]预测器及如何访问预测器的例子。


下面具体实现一个[10,2]的关联预测器

[10,2]关联预测器表示使用前10个分支行为去从2^10个分支预测中进行选择,每一个预测是对应于单个分支的2位预测器。最近10个分支的全局历史可以记录在一个10位移位寄存器中,每一位记录着该分支是被执行还是未被执行。实验要求限制30K空间,即2^10*2*分支选择的入口数目=30K,得到分支选择的入口数目是15,为方便编程,近似使用16bit入口数目,即用低4位地址作为入口地址。于是,对分支预测缓冲站可由分支地址的低4位拼接上10位全局历史记录而得到。[10,2]关联预测器设计如下图所示。


2位预测期可以表示4种状态,计数器在分支执行时加1,不执行时减1;计数器在00或11时处于饱和状态。2位预测器状态转移情况如下图。


所设计的[10,2]关联预测器大小为: 2^10×2 ×16=32K bit。

Tournament预测器

Tournament预测器使用两个预测期:一个基于全局信息的Global Predictor,以及一个基于局部信息的Local Predictor,并使用一个选择器在局部预测器与全局预测器中做出选择。具体设计如下:


全局预测器:使用最后12个分支跳转情况进行索引,即全局预测器也有2^12=4K个入口,每个入口都是一个标准的两位预测器。
局部预测器:设计为两层,上面一层是一个局部历史记录,使用指令地址的低10位进行地址索引,即有2^10=1K个入口,每个入口10位,分别对应这个入口最近的10个分支,即最近10次分支的跳转情况,这种10位历史记录允许对10个分支进行记录和预测,从局部历史记录选择出的入口对一个1K的入口表进行索引,这些入口由3位计数器构成,以提供本地预测。
选择器:使用分支局部地址的低12位分支局部地址索引,即有2^12=4K个选择器,每个索引得到一个两位计数器,用来选择使用局部预测器还是使用全局预测器的预测结果。在设计时默认使用局部预测器,当两个预测器都正确或都不正确时,不改变计数器;当全局预测器正确而局部预测器预测错误时,计数器加1,否则减1。其状态转移情况如下图。


所设计的Tournament预测器大小为: 2^12×2+2^10×10+2^10 ×3+2^12×2=29K bit。

*此外,在搜集资料时发现有些文献的选择器使用全局历史,即最近12个分支的情况作为选择器的两位计数器,实验时也尝试了如下设计,但结果证明第一种情况更好。


分支历史表预测器

最简单的动态分支预测方案是分支历史表。分支历史表是一个较小的按照分支地址的低位地址部分进行访问的存取器。即存储器中包含n位预测位以说明分支是否曾成功转移,在实验中实现此种简单的2bit分支历史表预测器作为性能对比。同样限制为30K内存,则2×分支历史选择的入口数目=30K,得到分支选择的入口数为30K,即可得到指令低14bit作为预测器索引。

所设计分支历史表预测器大小为: 2^14×2=32K bit。


实验代码

[cpp]  view plain copy
  1. // Branch Predication Simulation  
  2. // Coded by Wei Lan (Student ID: 1201214149)  
  3.   
  4. #include <iostream>  
  5. #include <fstream>  
  6. #include <sstream>  
  7. #include <string>  
  8. #include <bitset>  
  9. #include <map>  
  10. #include <vector>  
  11. #include <set>  
  12. #include <cmath>  
  13. using namespace std;  
  14.   
  15. // global variables  
  16. #define BITS4  0x0000f  
  17. #define BITS10 0x003ff  
  18. #define BITS12 0x00fff  
  19. #define BITS14 0x03fff  
  20.   
  21. // 2-bit branch history table predictor  
  22. vector<bitset<2> > branch_history_table(pow((float)2,14),bitset<2>(string("00")));  
  23.   
  24. // [10,2] correlating predictor  
  25. const int M=10;  
  26. const int N=2;  
  27. const int ADD_INDEX=14-M;  
  28. int branch_saved=0;  
  29. int predict_true=0,predict_false=0,actual_true=0,actual_false=0;  
  30. bitset<M> latest_branch(string("0000000000"));  
  31. vector<vector<bitset<N> > > correlating_predictor_table(pow((float)2,ADD_INDEX),vector<bitset <N> >(pow((float)2,M), bitset<N>(string("00"))));  
  32.   
  33. // tournament predictor  
  34. vector< bitset<10> > local_history_table(pow((float)2,10), bitset<10>(string("0000000000")));  
  35. vector< bitset<3> > local_predictor_table(pow((float)2,10),bitset<3>(string("000")));  
  36. vector< bitset<2> > global_predictor_table(pow((float)2,12), bitset<2>(string("00")));  
  37. bitset<12> global_history_table(string("000000000000"));  
  38. int global_saved=0;  
  39. vector<bitset<2> > selecotors(pow((float)2,12), bitset<2>(string("00")));  
  40.   
  41. // predition fuction  
  42. bool correlating(string current_pc, string next_pc);  
  43. bool tournament(string current_pc, string next_pc);  
  44. bool bht(string current_pc,string next_pc);  
  45.   
  46. int main(){  
  47.     string filenames[7]={"gcc.log""compress.log""crafty.log""gzip.log""mcf.log""parser.log""vpr.log"};  
  48.     double bht_average=0.0,correlating_average=0.0,tournament_average=0.0;  
  49.     for(int i=0;i<7;i++){  
  50.         cout<<"Testing file: "<<filenames[i]<<endl;  
  51.         ifstream fin(filenames[i]);  
  52.         int bht_predict_correct=0,bht_predict_wrong=0,  
  53.             correlating_predict_correct=0,correlating_predict_wrong=0,  
  54.             tournament_predict_correct=0,tournament_predict_wrong=0;  
  55.         string line;  
  56.         while(getline(fin,line)){  
  57.             stringstream theline(line);  
  58.             theline<<line;  
  59.             string current_pc;  
  60.             string next_pc;  
  61.             theline>>current_pc;  
  62.             theline>>next_pc;  
  63.             if(bht(current_pc,next_pc))  
  64.                 ++bht_predict_correct;  
  65.             else  
  66.                 ++bht_predict_wrong;  
  67.             if(correlating(current_pc,next_pc))  
  68.                 ++correlating_predict_correct;  
  69.             else  
  70.                 ++correlating_predict_wrong;  
  71.             if(tournament(current_pc,next_pc))  
  72.                 ++tournament_predict_correct;  
  73.             else  
  74.                 ++tournament_predict_wrong;  
  75.   
  76.         }  
  77.         float bht_correct_rate=(float)(bht_predict_correct)/(float)(bht_predict_correct+bht_predict_wrong);  
  78.         cout<<"The correct rate for 2-bit branch history table predictor is: "<<bht_correct_rate<<endl;  
  79.         bht_average+=bht_correct_rate;  
  80.         float correlating_correct_rate=(float)correlating_predict_correct/(float)(correlating_predict_correct+correlating_predict_wrong);  
  81.         cout<<"The correct rate for ("<<M<<","<<N<<") correlating predictor is: "<<correlating_correct_rate<<endl;  
  82.         correlating_average+=correlating_correct_rate;  
  83.         float tournament_correct_rate=(float)tournament_predict_correct/(float)(tournament_predict_correct+tournament_predict_wrong);  
  84.         cout<<"The correct rate for tournament predictor is: "<<tournament_correct_rate<<endl;  
  85.         tournament_average+=tournament_correct_rate;  
  86.         cout<<endl;  
  87.         fin.close();  
  88.     }  
  89.     bht_average /=7.0;  
  90.     correlating_average /=7.0;  
  91.     tournament_average /=7.0;  
  92.     cout<<"Average: "<<bht_average<<" "<<correlating_average<<" "<<tournament_average<<endl;  
  93.   
  94.     return 0;  
  95. }  
  96.   
  97. bool correlating(string current_pc, string next_pc){  
  98.     bool jump_actual=false,jump_predict=false;  
  99.     long current_add=strtol(current_pc.c_str(), NULL, 16);  
  100.     long next_add=strtol(next_pc.c_str(), NULL, 16);  
  101.   
  102.     bitset<ADD_INDEX> current_add_low=bitset<ADD_INDEX>(current_add & BITS4);  
  103.     if(correlating_predictor_table[current_add_low.to_ulong()][latest_branch.to_ullong()].at(1)==1)  
  104.         jump_predict=true;  
  105.   
  106.     if((next_add-current_add)!=4)  
  107.         jump_actual=true;  
  108.       
  109.     // Reset predictor and tables  
  110.     if(jump_actual){  
  111.         long tmp_predict=correlating_predictor_table[current_add_low.to_ulong()][latest_branch.to_ullong()].to_ulong();  
  112.         tmp_predict=(tmp_predict+1)>3 ? 3: (tmp_predict+1);  
  113.         correlating_predictor_table[current_add_low.to_ulong()][latest_branch.to_ullong()]=bitset<N>(tmp_predict);  
  114.     }  
  115.     else {  
  116.         long tmp_predict=correlating_predictor_table[current_add_low.to_ulong()][latest_branch.to_ullong()].to_ulong();  
  117.         tmp_predict=(tmp_predict-1)<0 ? 0: (tmp_predict-1);  
  118.         correlating_predictor_table[current_add_low.to_ulong()][latest_branch.to_ullong()]=bitset<N>(tmp_predict);  
  119.     }  
  120.     long tmp_latest=latest_branch.to_ulong();  
  121.     latest_branch=bitset<M>( (tmp_latest << 1 ) & BITS10);  
  122.     latest_branch[0]=jump_actual ? 1 : 0;  
  123.     return !(jump_actual ^ jump_predict);  
  124. }  
  125.   
  126.   
  127.   
  128. bool tournament(string current_pc, string next_pc){  
  129.     bool jump_actual=false,jump_predict=false,  
  130.         local_predict=false,global_predict=false;  
  131.     long current_add=strtol(current_pc.c_str(), NULL, 16);  
  132.     long next_add=strtol(next_pc.c_str(), NULL, 16);  
  133.     // Local predict   
  134.     int local_index=current_add & BITS10;  
  135.     if(local_predictor_table[local_history_table[local_index].to_ulong()].at(2)==1){  
  136.         local_predict=true;  
  137.     }  
  138.     // Global predict  
  139.     if(global_predictor_table[global_history_table.to_ulong()].at(1)==1){  
  140.         global_predict=true;  
  141.     }  
  142.     if(selecotors[current_add & BITS12].at(1)==0)  
  143.         jump_predict=local_predict;  
  144.     else  
  145.         jump_predict=global_predict;  
  146.   
  147.     // Update local and predictors and tables  
  148.     if((next_add-current_add)!=4)  
  149.         jump_actual=true;  
  150.   
  151.     if(jump_actual){  
  152.         long local_tmp=local_predictor_table[local_history_table[local_index].to_ulong()].to_ulong();  
  153.         local_tmp=(local_tmp+1) > 7 ? 7 : (local_tmp+1) ;  
  154.         local_predictor_table[local_history_table[local_index].to_ulong()]=bitset<3>(local_tmp);  
  155.     }  
  156.     else{  
  157.         long local_tmp=local_predictor_table[local_history_table[local_index].to_ulong()].to_ulong();  
  158.         local_tmp=(local_tmp-1) < 0 ? 0 : (local_tmp-1) ;  
  159.         local_predictor_table[local_history_table[local_index].to_ulong()]=bitset<3>(local_tmp);  
  160.     }  
  161.     long local_history_tmp=local_history_table[local_index].to_ulong();  
  162.     local_history_tmp=(local_history_tmp<<1) & BITS10;  
  163.     local_history_table[local_index]=bitset<10>(local_history_tmp);  
  164.     local_history_table[local_index][0]= jump_actual ? 1: 0;  
  165.   
  166.     // Update global and predictors and tables  
  167.     if( jump_actual){  
  168.         long global_tmp=global_predictor_table[global_history_table.to_ulong()].to_ulong();  
  169.         global_tmp=(global_tmp+1) > 3 ? 3 : (global_tmp+1) ;  
  170.         global_predictor_table[global_history_table.to_ulong()]=bitset<2>(global_tmp);  
  171.     }  
  172.     else {  
  173.         long global_tmp=global_predictor_table[global_history_table.to_ulong()].to_ulong();  
  174.         global_tmp=(global_tmp-1) < 0 ? 0 : (global_tmp-1) ;  
  175.         global_predictor_table[global_history_table.to_ulong()]=bitset<2>(global_tmp);  
  176.     }  
  177.     long global_history_tmp=global_history_table.to_ulong();  
  178.     global_history_tmp=( (global_history_tmp<<1) & BITS12);  
  179.     global_history_table=bitset<12>(global_history_tmp);  
  180.     global_history_table[0]=jump_actual ? 1:0;  
  181.   
  182.     // Update selecotrs  
  183.     if(local_predict^global_predict){  
  184.         if( local_predict^jump_actual ){  
  185.             long selecotor_tmp=selecotors[current_add & BITS12].to_ulong();  
  186.             selecotor_tmp=(selecotor_tmp+1)>3 ? 3:  (selecotor_tmp+1);  
  187.             selecotors[current_add&0xfff]=bitset<2>(selecotor_tmp);  
  188.         }  
  189.         else if(global_predict^jump_actual ){  
  190.             long selecotor_tmp=selecotors[current_add & BITS12].to_ulong();  
  191.             selecotor_tmp=(selecotor_tmp-1)<0 ? 0:  (selecotor_tmp-1);  
  192.             selecotors[current_add&0xfff]=bitset<2>(selecotor_tmp);  
  193.         }  
  194.     }  
  195.   
  196.     return !(jump_actual ^ jump_predict);  
  197. }  
  198.   
  199. bool bht(string current_pc,string next_pc){  
  200.     bool jump_actual=false,jump_predict=false;  
  201.     long current_add=strtol(current_pc.c_str(), NULL, 16);  
  202.     long next_add=strtol(next_pc.c_str(), NULL, 16);  
  203.   
  204.     if((next_add-current_add)!=4)  
  205.         jump_actual=true;  
  206.   
  207.     if(branch_history_table[current_add & BITS14].at(1))  
  208.         jump_predict=true;  
  209.   
  210.     // Update histroy table  
  211.     if(jump_actual){  
  212.         long tmp=branch_history_table[current_add & BITS14].to_ulong();  
  213.         tmp=(tmp+1)>3 ? 3:(tmp+1);  
  214.         branch_history_table[current_add & BITS14]=bitset<2>(tmp);  
  215.     }  
  216.     else{  
  217.         long tmp=branch_history_table[current_add & BITS14].to_ulong();  
  218.         tmp=(tmp-1)<0 ? 0:(tmp-1);  
  219.         branch_history_table[current_add & BITS14]=bitset<2>(tmp);  
  220.     }  
  221.     return !(jump_actual ^ jump_predict);  
  222.   
  223. }  


(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值