参考来源:《超标量处理器设计》—— 姚永斌
BHR - Branch History Register
通过一个BHR寄存器记录一条分支指令在过去的历史状态。
当历史状态规律时,可以提高分支预测准确率,也成为自适应两级分支预测。
一个位宽为n的BHR寄存器可以记录一条分支指令过去N次结果。
每个分支指令都是通过BHR去寻址PHT (Pattern History Table), 通过PHT存放BHR不同取值对应的两位饱和计数器数值,可以建立BHR的规律信息。
PHT每个表项只是存储饱和计数器的值,饱和计数器本身独立于PHT之外。
当一条分支指令结果产生时,读取PHT中对应的数值并更新,再将结果写回PHT。
基于局部历史的分支预测用例
假设有一条分支指令,它的BHR位宽是2位,意味着此分支指令前两次结果会被保存在BHR寄存器中。
每个BIT的数值0代表指令没有跳转,数值1代表指令有跳转。
同时存在一个PHT拥有4个entry对应BHR的4种可能情况(00/01/10/11)。
当出现规律性跳转时,例如(01 ➡ 10 ➡ 01 ➡ 10),BHR寄存器中就会交替出现0和1。
这样对于PHT来说,01跳转entry 1很快会达到strongly not taken状态,10跳转entry 2很快会达到strongly taken状态。
因此当BHR为01时,PHT就会给出会不跳转的结果(strongly not taken)。
当BHR为10时,PHT就会给出会跳转的结果(strongly taken)。
基于局部历史的分支预测要求
更宽的BHR可以记录更多的历史记录,提高分支预测精确度。
也需要更长的时间来训练预测方向,同时也会占用更多的资源。
一个规律跳转序列中,连续相同的跳转情况最多有P位,P就是这个序列的循环周期。
BHR的宽度N则是不能小于循环周期P。
由于使用了PC一部分寻址BHR和PHT,可能存在重名问题影响预测结果。
考虑到BHT位宽决定对PHT entry条目的占用数量,因此多个BHR可以指向PHT多个不同位置。
但是当两个分支指令指向同一个BHR,就会对应到PHT同一个饱和计数器。
以及两个BHR内容相同时,会指向同一个PHT中的饱和计数器。
为避免此情况,会对PC值以及BHR值进行HASH或者XOR处理。
基于全局历史的分支预测
基于局部历史的预测方法只考虑了指令自身过去的执行情况,但是一条分支指令结果有些时候与它之前的分支指令结果相关。
例如存在三条分支指令B1,B2,B3。当B1和B2执行后,B3不会执行。
因此在预测B3时需要将B1和B2的结果也考虑进去,也就是基于全局历史的分支预测。
由全局历史寄存器(Global History Register, GHR)记录最近执行的所有分支指令结果。
每一次分支指令结果都会从GHR寄存器最低位移入,并弹出最高位数据。
GHR也需要借助PHT的饱和计数器数值判断是否跳转。
最理想的情况就是每个分支指令都有一个PHT,根据当前的GHR寻址自身的PHT。
所有的PHT组成的表格位PHTs,为避免占用过多的空间,一般采用HASH对PC处理建立更小位宽的PHT。