支持的分支预测类型
l二级分支预测 :也就是通过移位寄存器(一级)和PHT表(二级),在PHT表中根据2位饱和计数器分析当前分支的跳转情况。
参数: N —— 一级入口数目
W —— 移位寄存器的宽度
M —— 二级入口数目
对于Gag :三个参数值为别为:1 W 2^W
Gap: 三个参数值为别为: 1 W M
l
参数:
对于
(只有一个移位寄存器,因此N为1,又因为当只有一个PHT表,因此,Gag中M是2^w,此时,通过移位寄存器,查找PHT表,得到分支情况;而在Gap中,不同的分支有不同的PHT表,因此需要利用分支指令的地址获取多个PHT表中的其中一个,因此M = K*2^w,其中的K应该是设定的PHT表的个数,而且,K应该是2的指数级)
Pag:三个参数值为别为: N W 2^W
Pap:三个参数值为别为: N W M
(此时,将同时利用分支指令的地址索引移位寄存器和PHT表,如果是PAG,那么,利用分支指令地址索引多个移位寄存器,获取的值再去索引PHT表,获取跳转情况,如果是PAP,则同时利用分支指令地址索引移位寄存器和PHT表,得到跳转情况)。
二位饱和计数预测模式
支持的预测方式是当 XX = 0X时不跳转
XX = 1X时跳转
预测不跳转
预测跳转
分支预测的各参数定义
1) 定义了分支预测的类型
enum bpred_class{ }
2) 定义了BTB(分支目的缓冲)表的结构
书中定义的BTB表含有三个部分:分支指令的地址,分支跳转的目的地址,以及预测结果
这儿的结构中定义了四个部分:分支指令的地址;针对当前地址的OP;如果分支跳转,那么跳转的目的地地址;以及形成BTB表的链表结构(双向链表)
3) 定义了二位饱和计数的预测结构,考虑到二级分支预测也使用了二位饱和计数器,因此利用union定义了各部分:
class -说明是二级分支预测还是bimod预测;
然后如果是bimod,那么需要定义一个计数器结构,即:bimod.size和bimod->table;
如果是二级分支预测,需要定义的类型为:寄存器的个数,PHT表的个数,移位寄存器中保存的分支历史长度;把分支历史和分支地址是否XOR的标志;指向历史表的指针和指向PHT表中的指针;
4) 定义了分支预测器:
定义分支预测的类型,以及指向的相应的预测器元素;
定义了BTB表的组数,以及BTB组中的相联程度,以及BTB表
定义了返回栈:返回栈的大小,返回栈的栈顶,而返回栈也是利用了BTB的结构
同时还定义了多个计数:方向预测的正确性(向前,向后——是否跳转)、地址预测的正确性(不仅是向前向后正确,还要有地址的正确。等等结构。
这儿不仅预测分支指令,其中还包括了程序间调用的返回等。
5) 定义了预测更新的消息
然后是各函数的声明
1) 创建分支预测器
2) 创建了分支方向预测器
3) 分支预测器配置的输出
4) 分支预测状态的输出
5) 在数据库(sdb)中存储分支预测的信息
6) 在主要的地点存储分支信息
7) 利用分支预测器处理下一条指令
8) 预防因为前瞻执行导致的错误
9) 对分支预测器中若干元素的更新
10) 为了调试导出分支预测器的信息。
各函数的具体说明
1) 创建一个分支预测器
看这个函数需要先看一下创建分支方向预测器的函数
根据class,首先创建分支方向预测器(包括二级、bimod等方向预测器)
然后继续根据分支预测器的类型class,分配返回栈
首先看一下BTB表的结构,如果BTB表大小为0或者不是2的指数倍,不行。然后根据BTB表的组×相联 分配空间
接下来把各项BTB结构挂接成为链表
在分配完BTB之后,分配返回栈结构。而返回栈其实就是一个数组
2) 创建一个分支方向预测器
首先分配一个结构大小的空间
然后是说明当前要创建的分支方向预测器的类型(class)
接下来是根据class按需要给其中的参数赋值:
如果是二级分支预测:参数有:
支持的预测方式是当
分支预测的各参数定义
1) 定义了分支预测的类型
enum bpred_class{ }
2) 定义了BTB(分支目的缓冲)表的结构
书中定义的BTB表含有三个部分:分支指令的地址,分支跳转的目的地址,以及预测结果
这儿的结构中定义了四个部分:分支指令的地址;针对当前地址的OP;如果分支跳转,那么跳转的目的地地址;以及形成BTB表的链表结构(双向链表)
3) 定义了二位饱和计数的预测结构,考虑到二级分支预测也使用了二位饱和计数器,因此利用union定义了各部分:
class -说明是二级分支预测还是bimod预测;
然后如果是bimod,那么需要定义一个计数器结构,即:bimod.size和bimod->table;
如果是二级分支预测,需要定义的类型为:寄存器的个数,PHT表的个数,移位寄存器中保存的分支历史长度;把分支历史和分支地址是否XOR的标志;指向历史表的指针和指向PHT表中的指针;
4) 定义了分支预测器:
5) 定义了预测更新的消息
然后是各函数的声明
1)
2)
3)
4)
5)
6)
7)
8)
9)
10) 为了调试导出分支预测器的信息。
各函数的具体说明
1)
2)
3)
4)
5)
6)
7)
8)
反正现在知道l2index是获取2位饱和计数器的值的索引的。
9)
注意,这儿是考虑了所有的指令,不仅仅是分支指令,即代码中的获取指令操作码的宏。
在这儿的预测中,首先是预测一下分支的方向,得到pdir1的结果。然后是对分支指令的跳转地址的预测。由于是预测条件分支,也就是说,非条件分支是不预测的。在这儿,先看一下对返回栈的处理。
如果在BTB中没有找到相应的指令地址,那么根据前面的pdir,分析是不是跳转,即只能给出方向
10)
11)
首先是判断是不是分支指令。
如果是分支指令,而且地址也对,那么预测正确数+1,否则是方向+1
这个函数是当分支指令执行完毕之后处理的。但不是很明白其中的stateful 预测是什么意思。针对BTB表的处理是有的更新,没有的话利用LRU替换。
以下是我写的一个模拟器的代码中的分支预测代码