3.6. Intel Nehalem中的分支预测
Nehalem中的分支预测机制公开文献甚少,测试结果尚未能完全解释。
误预测惩罚
因为更长的流水线,误预测惩罚更甚于Core2。测量到的误预测惩罚至少是17个时钟周期。
条件跳转的模式识别
分支预测机制被改进以补偿更长的误预测时延。条件跳转由结合了一个或多个双层预测器机制及循环计数器的混合预测器处理。另外,有一个机制用于间接跳转与间接调用的预测。
具有循环行为分支的预测,循环计数最多到64。不使用全局历史表保存每个分支的循环计数器,循环计数器有自己的32项缓冲。循环的预测不依赖循环内其他分支的数目。嵌套循环能完美预测。
使用带有18比特全局历史缓冲及大小未知的历史模式表的双层预测器预测没有循环行为的分支。除了简单的循环模式,预测重复分支模式的能力,根据第8页解释的带有全局历史缓冲预测器的规则,依赖于循环内跳转的数目。显然,存在两个18比特历史缓冲。第一个历史缓冲包含所有的跳转与分支,包括无条件跳转,但不包括永远不采用的分支。第二个历史缓冲仅包含某些分支,大概是最重要的那些。这改进了最多包含9个跳转的循环内某些分支的预测。我尚不能完全解释测试结果。使用历史缓冲的准则尚未找到。算法是非对称的,因此连续不采用的最大事件数大于连续采用的最大事件数。这两个数值依赖于循环内跳转的数目。
间接跳转与调用的模式识别
使用与分支指令相同的双层预测器预测间接跳转与间接调用(不包括返回)。没有循环行为的分支与间接跳转/调用共享历史缓冲,但可能不共享BTB。
BTB结构
分支目标缓冲有两层,就像双层缓存系统。对不同的分支类型可能有不同的分支目标缓冲。我还没办法测量分支目标缓冲的大小。
函数返回的预测
对近程返回,栈缓冲有16项。
文献:"AMethod and apparatus for branch prediction using a second level branchprediction table". WO Patent 2000/014628.
3.7. Intel SandyBridge与Ivy Bridge中的分支预测
通过不对循环使用独立的预测器,SandyBridge逆转了更复杂分支预测算法的潮流。分支预测机制的重新设计可能是必须的,以处理新的μop缓存(参考下面的第108页)。这个简化的进一步原因可能是期望降低流水线长度,因而误预测惩罚。IvyBridge看起来非常类似于SandyBridge。
误预测惩罚
由于μop缓存,误预测惩罚通常小于Nehalem(参考下面的第108页)。测量的误预测惩罚是,μop缓冲内的分支15或更多周期,在1级代码缓存中的分支稍微更多。
条件跳转的模式识别
看起来有一个带有32比特全局历史缓冲与未知大小历史模式表的双层预测器。不存在特别的循环预测器。嵌套循环与包含分支的循环预测不是特别好,尽管有时好于第8页规则的结果。
间接跳转与调用的模式识别
使用与分支指令相同的双层预测器预测间接跳转与间接调用(不包括返回)。
BTB结构
根据非官方的谣言,SandyBridge的分支目标缓冲要大于Nehalem。不知道它是否为一层,就像在Core2及更早的处理器中,或是像Nehalem中双层。每16字节代码,它可以处理最多4条调用指令。如果每16字节代码有超过3条分支指令,条件跳转要低效些。
函数返回的预测
对近程返回,栈缓冲有16项。
3.8. Intel Haswell,Broadwell与Skylake中的分支预测
分支预测器看起来在Haswell中被重新设计了,但其结构知之甚少。
跳转与分支测量得到的吞吐率,对跳转及预测被采用分支,在每时钟周期一条分支到每两个时钟周期一条分支。预测不采用分支有更高的吞吐率,达到每时钟周期两条分支。
对每16字节代码不超过一个分支的多达128个分支,可以观察到采用分支每时钟周期一条的高吞吐率。如果每16字节代码分支多于一个,吞吐率降低到每两个时钟周期一条。如果在代码的一条关键路径有超过128个分支,并且它们彼此被至少16个字节隔开,显然,前128个分支有高吞吐率,剩下的有低的吞吐率。
这些观察可能表示存在两个分支预测方法:一个绑定到μop缓存与指令缓存的快速方法,一个使用分支目标缓冲的较慢方法。
误预测惩罚
分支误预测惩罚变化很大。测量值为15到20个时钟周期。
条件跳转的模式识别
处理器能够预测非常长的重复跳转模式,很少或没有误预测。我发现对可以预测的跳转模式长度没有特别的限制。次数多达32或更多一些的循环可以被成功预测。嵌套循环与循环内分支的预测也良好。
间接跳转与调用的模式识别
间接跳转与间接调用预测良好。
BTB结构
分支目标缓冲的结构未知。看起来相当大,
函数返回的预测
对近程返回,栈缓冲有16项。
3.9. Intel Atom,Silvermont与Knights Landing的分支预测
在IntelAtom与Silvermont处理器中,分支预测机制是带有全局历史表,遵循第8页描述原理的双层自适应预测器。分支历史寄存器有12比特。在Atom上模式历史表有4096项,由线程共享。分支目标缓冲有128项,组织为4路32组。在Silvermont上这些缓冲的大小未知,但可能更大,且不在线程间共享。
无条件跳转在全局历史表中没有项,但总是采用与总是不采用分支有。
Silvermont在流水线的指令获取阶段及稍后的解码阶段有分支预测,根据Realworldtech中的论文,后者可以纠正前者中的错误.
与某些文档所说相左,根据我的测试,循环没有特殊的预测器。循环以与其他分支相同的方式预测,遵循在第8页描述的规则。
误预测惩罚
误预测一个分支的惩罚是11-13个时钟周期。
通常出现一个分支在模式历史表有正确的项,但在小得多的分支目标缓冲中没有项。如果一个分支被正确预测为采用,但因为缺少的BTB项,没有目标可以被预测,那么惩罚将大约是7个时钟周期。
间接分支的预测
某些文档说Silvermont对间接分支有一个历史预测器,但这与我的测试不符。在KnightsLanding上我找到了对间接分支的模式预测,但在Silvermont上没有。在Silvermont上,间接分支被预测为去到上一次的目标。
返回栈缓冲
在Atom上返回栈缓冲有8项,Silvermont与KnightsLanding是16项。
3.10. VIA Nano中的分支预测
根据G.Glenn Henry: "The VIA Isaiah Architecture", Centaur Technology, 2008(www.via.com.tw),VIANano处理器有带有几个不同分支预测器,多数投票机制,及一个元预测器的混合预测机制。
根据上面的提到的文档,分支目标缓冲有4096项,4路组相连。
对每个16字节代码,分支目标缓冲以两个项连接到代码缓存。如果一个16字节代码块包含超过两个分支,那么多出来的分支使用更简单、更慢的机制。这符合我的测试。如果一个16字节代码块包含超过2个跳转、分支、调用或返回,分支预测变慢。
在我的测试中,该机制的行为几乎就是一个带有结合了12比特局部历史与2比特全局历史的历史表的融合双层自适应预测器。局部历史信息被保存,与之相关,代码缓存对每个16字节代码块提供一定的储存。
预测的表现依赖于在同一个16字节代码块中的跳转数。如果在每个16字节代码块中分支或跳转不超过一个,预测最好。如果在一个16字节代码块中有两个分支或跳转,每个分支保存局部历史的比特数减少,即使其中一个跳转是无条件的。如果有两个跳转或分支,其中一个总是被采用,预测尤其糟糕。如果在下一个16字节代码块中有超过两个跳转或分支,那么多出来的跳转或分支将使用更慢且较差的预测方法。
循环分支的行为稍有不同。内部没有跳转的循环,直到循环次数15-20,都可以被预测。内部有一个或更多跳转的循环,直到次数12-16,可以被预测。行为会变化,并不总是可重现。
间接跳转被预测为去到上一次的目标。
返回栈缓冲看起来很深。在我的测试里,即使在嵌套非常深的子例程中,所有的返回都被正确预测。
误预测惩罚通常是16个时钟周期,最多20。
如果一个分支后跟一条序列化指令,比如CUPID,分支预测机制失效,但在测试时,这必须被考虑入内。