★ 继续学习体系结构的知识。
1. 什么是分支预测
程序中有一种叫做分支指令的指令,如果在取指令阶段就可以预知本周期所取指令中是否存在分支指令,并且知道其方向(跳转/不跳转)以及目标地址,就可以从在下个周期从分支指令的目标地址开始取指,让流水线正确进行,提高处理器的执行效率。
(1)静态分支预测:预测分支指令总是不执行的,处理器总是顺序地取指令。
(2)动态分支预测:并不简单预测分支指令一直跳转或不跳转,而是根据分支指令在过去一段时间的执行情况来决定预测结果。
分支预测的最好时机是在当前周期得到取指令地址的时候,在取指令的同时进行分支预测,这样在下个周期就可以根据预测的结果继续取指令。
2. RISC分支指令类型
(1)根据分支指令是否执行的条件判断,分为无条件跳转分支指令与条件跳转分支指令。
(2)根据分支指令跳转地址的计算方式,分为直接跳转分支指令与间接跳转分支指令。
无条件/条件:无条件跳转分支指令一定会发生跳转,条件跳转分支指令需要根据条件判断是否跳转。
直接/间接:直接指跳转的目标地址可以根据指令编码的立即数和当前地址直接计算,间接指跳转的目标地址需要根据从寄存器索引的操作数计算。
组合来看,可以细分为四种跳转指令:
(1)无条件直接跳转分支指令,如RISC-V中的jal(jump and link)指令;
(2)无条件间接跳转分支指令,如RISC-V中的jalr(jump and link-register)指令;
(3)条件直接跳转分支指令,如RISC-V中的beq等指令(RISC-V中有6条此类指令);
(4)条件间接跳转分支指令,RISC-V中没有此种指令。
3. 分支指令的方向预测
3.1 基于两位饱和计数器的分支预测
(1)核心理念: 该分支预测方法基于这样一个观察:在程序执行过程中,很多分支指令具有一定的局部性,即它们在连续多次执行时,往往会倾向于选择同一分支方向(跳转或不跳转)。
- 稳定性假设:如果一条分支指令连续两次执行的方向都相同,那么它在下一次执行时很可能继续保持这一方向。
- 过滤假设:对于那些仅偶尔改变分支方向的指令,预测器不会因单次方向变化而立即改变预测结果,而是会“过滤”掉这种偶然变化,以减少预测错误。
(2)算法过程:根据一条分支指令的前两次执行结果预测本次方向,用四个状态机表示。
- Strongly taken(饱和状态,预测跳转,编码11):表示分支指令在过去连续多次(通常为两次)都跳转,预测器对下一次执行强烈倾向于跳转。
- Weakly taken(不饱和状态,预测跳转,编码10):表示分支指令最近一次跳转,但之前有一次未跳转,预测器较弱地倾向于跳转。
- Weakly not taken(不饱和状态,预测不跳转,编码01):表示分支指令最近一次未跳转,但之前有一次跳转,预测器较弱地倾向于不跳转。
- Strongly not taken(饱和状态,预测不跳转,编码00):表示分支指令在过去连续多次(通常为两次)都不跳转,预测器对下一次执行强烈倾向于不跳转。
状态机处于饱和状态时,只有两次预测失败才会改变结果。适用于分支指令方向总是朝一个方向,状态机处于饱和状态,则正确率较高。
状态机的工作机制:
-
状态转移规则:每当分支指令执行后,根据实际执行结果(跳转或不跳转),状态机会按照预设的规则更新到相应的状态。例如,若当前状态为“Strongly not taken”,而分支指令实际跳转,状态机将转移到“Weakly taken”。
-
饱和状态的特性:当状态机处于“Strongly taken”或“Strongly not taken”(饱和状态)时,预测器对分支方向的预测具有较高的置信度。在这种状态下,即使分支指令的实际执行结果与预测相反(即预测错误),也需连续两次这样的错误才能使状态机退出饱和状态,