为什么将分支目标缓冲区设计为缓存



BHT不是缓存,它不需要是缓存,因为如果访问时出错也没关系。然而,BTB被设计为缓存,因为它总是必须返回命中或未命中。为什么BTB不能出错?

BTB可能会犯错误,当跳转指令实际执行(或解码,用于直接分支)时,会检测到错误推测,导致前端重新转向从正确位置提取时出现气泡。

或者,对于间接分支,由于无序的推测性执行,核心可能不得不回滚到最后一个已知的良好状态,就像从条件分支的错误分支方向恢复一样。

BTB可能会出现错误命中,目前一些实现通过使用分部标记来利用这一点。(同样,每个集合可以有一个条目完全没有标记;在直接映射的BTB中,没有条目会被标记。传统的集合关联设计,每种方式都有(部分)标记,作为方式选择的一部分,提供了"免费"的未命中检测。)正如Peter Cordes的回答所指出的,这个错误可以在以后的过程中被发现并纠正。

识别BTB失误确实可以抑制猜测。如果BTB用于预取超过指令缓存未命中的指令流,则避免缓存污染和带宽浪费的错误分配可能会对性能产生影响。当性能受到功率或热因素的限制时,即使可以快速检测和纠正错误,也可以避免误判,从而节省一些功率/热量,从而有可能提高性能。

对于两级BTB,命中指示可以允许该分支不访问L2 BTB。除了能量效率之外,L2 BTB可能已经被设计为提供较低的带宽,或者与另一个紧密耦合的获取引擎共享(因此一个获取引擎未使用的带宽可以被另一个使用)。

此外,BTB未命中的指示可以用于改进分支方向预测。未命中表示分支在最近的历史中可能没有被执行(无论是最近没有执行还是在最近执行期间没有执行);分支方向预测器可以选择覆盖所采取的预测(在解码时计算目标)或者可以选择将该预测视为低置信度(例如使用动态预测或者给予从其他线程获取的优先级)。前者有效地从预测器中过滤出从未提取的分支(允许具有预测提取的破坏性别名);两种未命中指示的使用都利用了旧分支信息不太可能准确的可能性。

BTB还可以提供一种简单的分支识别方法。BTB未命中预测获取不包含潜在的已获取分支(过滤掉非分支和从未获取的分支)。这避免了分支方向预测器必须预测非分支指令未执行(或者当分支方向预预测器预测执行时,在BTB错误命中的指令解码之后重定向获取)。这会将非分支添加到过滤中,以避免破坏性混叠。(可以使用单独的分支标识符来过滤非分支指令,并区分非条件、间接和返回指令,这些指令可能使用不同的目标预测器,并且可能不需要方向预测。)

如果BTB提供每地址方向预测或用于方向预测的其他信息,则未命中指示可以允许方向预测器使用其他方法来提供这样的信息(例如,静态分支预测)。静态预测可能不是特别准确,但它可能比具有已取偏差的"随机"预测更准确(因为从未取过的分支可能永远不会进入BTB,并且替换可能基于最近最少取的分支);"静态"预测器也可以利用BTB未命中的事实。如果使用一致预测器(其中将静态偏差与预测异或以减少破坏性混叠,所采用的带偏已取分支与未采用的带偏置未取分支具有相同的预测器更新),则需要每个地址的偏差。

L1 BTB也可以与L1指令高速缓存集成,特别是对于分支地址相对目标,使得不仅没有遗漏检测(存在所有方式的标签),而且BTB提供的目标甚至可能不是预测(避免重新计算目标的需要)。这将需要用于间接分支的额外预测资源(并且L2 BTB可以用于支持指令高速缓存未命中下的预取),但是可以避免显著的冗余存储(因为这样的分支指令已经存储了偏移)。

即使BTB未命中确定不是必需的,但它可能是有用的。

最新更新