实验 分支预测器
CSAPP黑书的实验,分支预测器。做了好几个不同的实现,放一个最终实现的还不错的版本的原理在这里。本地其实有存实验报告,发上来留作纪念吧 :)
一、最终实现
最终实现了融合本地历史与全局历史,为分支指令选取合适的预测器的一种算法。
其中,实现了3-bits状态的预测器状态机、为每个指令分配了独立的状态机、测试不同的hash函数等实验目的
实现原理
该预测器由两个预测器和一个选择器构成,融合局部历史与全局历史信息。查询资料发现,这种方法即Tournament 预测器的原理
全局预测器: 用PC的低12位进行索引,共 2 12 = 4 K 2^{12}=4K 212=4K个入口,每个入口对应一个2位状态预测
局部预测器: 用PC的低10位进行局部历史表的索引,共 2 10 = 1 K 2^{10}=1K 210=1K个入口,每个入口对应10位历史(记录最近10次该指令的跳转情况);取出一个指令的10位历史后,与PC做异或,作为预测器的索引,共 2 10 = 1 K 2^{10}=1K 210=1K个入口,每个入口对应一个3位状态预测
选择器: 用来选择使用哪个预测器进行预测。若局部预测和全局预测都正确或者都错误,则不变;若全局预测正确而局部预测错误,则饱和计数+1;反之-1;初始值默认为局部预测器。
二、分析
(1) 空间分析
所设计的预测器大小为: 2 12 × 2 + 2 10 × 10 + 2 10 × 3 + 2 12 × 2 = 29 K 2^{12}×2+2^{10}×10+2^{10} ×3+2^{12}×2=29K 212×2+210×10+210×3+212×2=29K bit。
(2) 每千条代码错误率
Baseline:Gshare框架
对比对象2:自己实现的另一个预测器([10,8]关联预测器)
MISPRED_PER_1K_INST | SHORT_30 | SHORT_28 | SHORT_27 |
---|---|---|---|
Gshare | 7.1043 | 0.0074 | 0.4710 |
[10,8]关联预测器 | 7.3131 | 0.0074 | 0.4710 |
Tournament预测器 | 3.8794 | 0.0079 | 0.5027 |
MISPRED_PER_1K_INST | LONG_1 | LONG_2 | LONG_3 | LONG_4 |
---|---|---|---|---|
Gshare | 0.5772 | 1.3861 | 7.7871 | 0.0052 |
[10,8]关联预测器 | 0.5886 | 1.3448 | 7.5990 | 0.0051 |
Tournament预测器 | 0.3858 | 1.1483 | 7.5775 | 0.0047 |
(3) 其他分析
① 取PC的部分地址做索引时,长度越接近PC的原始长度,预测失败率会下降。
② 尝试其他hash函数的时候,有的效果与异或操作可以基本持平但仍差一些,例如加法等,会使错误率有一定的提高。
三、结论
① 使用全局的历史能明显降低预测失误率,在空间和时间有限,无法使用机器学习的情况下,想办法使用上全局历史是一个不错的优化选择。
② 2-bits状态机用来预测已经可以达到比较理想的效果,继续扩展到3位甚至更多位能一定程度上弥补没有全局历史的缺点,但相比于2位而言,提升空间不算大。所以,有时为了空间考虑,使用2-bits的状态机就可以实现必要的功能。