从P5时代开始的一种先进的,解决处理分支指令(if-then-else)导致流水线失败的数据处理方法,由CPU来判断程序分支的进行方向,能够加快运算速度。
当包含流水线技术的处理器处理分支指令时就会遇到一个问题,根据判定条件的真/假的不同,有可能会产生转跳,而这会打断流水线中指令的处理,因为处理器无法确定该指令的下一条指令,直到分支执行完毕。流水线越长,处理器等待的时间便越长,因为它必须等待分支指令处理完毕,才能确定下一条进入流水线的指令。
分支预测技术便是为解决这一问题而出现的。
分支预测技术包含编译时进行的静态分支预测和硬件在执行时进行的动态分支预测。
静态分支预测
最简单的静态分支预测方法就是任选一条分支。这样平均命中率为50%。更精确的办法是根据原先运行的结果进行统计从而尝试预测分支是否会跳转。
任何一种分支预测策略的效果都取决于该策略本身的精确度和条件分支的频率。
动态分支预测
动态分支预测是近来的处理器已经尝试采用的的技术。最简单的动态分支预测策略是分支预测缓冲区(Branch PredictionBuff)或分支历史表(branch history table)。
====================================--=====典型分支预测分析=========================================
1.分支指令预测
在程序中一般都包含有分支转移指令,据统计,平均每七条指令中就有一条是分支转移指令.在指令流水线结构中,对于分支转移指令相当敏感。假设在80486的指令流水线中的第一条指令已进入到译码阶段,而第二条指令已进入到提取阶段(准备进入译码器),如果发现第一条指令是分支指令(如跳转到某个地址),则指令预取队列中下一条及下下条等指令预取无效。这时(确切地说,等到第一条指令执行期间形成了分支的目标地址),需从目标地址中现取指令,并交付执行,同时应立即清除指令预取队列,再将目标地址后面的指令预取过来填到队列中。这表明,一遇到分支指令,整个指令流水线就被打乱一次,稍后才能恢复到正常。显然,这影响了机器的运行速度。为此,在Pentium处理器中使用了分支目标缓冲器(BranchTarget Buffer,BTB)来预测分支指令。
BTB实际是一个能存若干(通常为256或512)条目的地址存储部件。当一条分支指令导致程序分支时,BTB就记下这条指令的目标地址,并用这条信息预测这一指令再次引起分支时的路径,预先从该处预取。下面看一下BTB在循环程序中应用。循环程序在程序设计中使用得十分普遍。在指令级目标程序中构成循环程序需要用转移指令(条件转移指令或无条件转移指令)。看下例:
MOV CX.100
LOOP: ……
……
DEC CX
JNZ LOOP
……
在第一次执行到JNZ指令时,预测的转移地址是存在BTB中的前面一条JNZ指令的目标地址,不是LOOP,这一次预测是错误的。但执行后目标地址LOOP便存入到BTB中。等到下一次执行到JNZ指令,就按BTB中的内容来预测,转移到LOOP,这是正确的。如此,一直到cx的值变为0之前,也都是对的。当再循环一次CX的值变为0时,JNZ指令因条件不成立而不实行转移,而预测仍是LOOP,预取仍按该预测进行,这是第二次预取错误。可见,该例中100次循环,有98次预测,确切地说,有98次预测指导下的预取是正确的。同理,对于1000次循环,就会有998次的预取是正确的。即循环次数越多,BTB带来的效益就越高。
2.推测执行与动态分支预测
推测执行技术又称预测执行技术。它的基本思想是:在取指阶段,在局部范围内预先判断下一条待取指令最有可能的位置,即在取指部件就具有部分执行功能,以便取指的分支预测,保证取指部件所取的指令是按照指令代码的执行顺序取入,而不是完全按照程序指令在存储器中的存放顺序取入。
动态分支预测是推测执行的一种具体做法,它是相对静态分支预测而言的。静态分支预测在指令到了译码器,进行译码时,利用BTB中目标地址信息预测分支指令的目标地址(如Pentium处理器那样);而动态分支预测的预测发生在译码之前,即对指令缓冲器(与8086、80386的指令预取队列基本相同,但有区别。)中尚未进入译码器中的那部分标明每条指令的起始和结尾,并根据BTB中的信息进行预测,这样发现分支指令要早。因此,对动态分支预测,一旦预测有误,已进入到流水线中需要清除的指令比静态分支预测时要少,从而提高了CPU的运行效率。