Intel, AMD及VIA CPU的微架构(4)

3.2.      P1中的分支预测

用于P1的分支预测机制与其他处理器差异极大。在Intel文档及别处找到的,关于这个主题的信息是误导性的,遵循这些文档中给出的建议很可能导致次优的代码。

P1有一个分支目标缓冲(BTB),它可以保存最多256条跳转指令的信息。BTB被组织为一个4路组相连缓存,每路64项。这意味着BTB不能持有超过4个组值相同的项。不像数据缓存,BTB使用一个伪随机替换算法,它意味着一个新项不一定替换相同组值的最近最少使用项。

每个项包含一个图3.1所示的饱和计数器。显然,设计者负担不起一个表示BTB项是否被使用的额外比特。取而代之,他们同等对待状态“强不采用”与“项未使用”。这是合理的,因为在P1中,一个没有BTB项的分支被预测为不采用。一个分支不会得到一个BTB项,直到它第一次被采用。不幸的是,设计者决定第一次采用的分支,应该去到状态“强采用”。这使得预测器的状态图看起来像这样:

图3.4. P1中的分支预测器

这当然是一个次优的设计,我有充分证据,这是一个设计缺陷。在一个具有不超过4对指令的紧凑循环中,这时循环控制分支在BTB有时间被更新之前再次被看到,饱和计数器的输出被直接转发到预取器。在这个情形中,状态可以从“强不采用”变到“弱不采用”。这表示最初的预期行为正如图3.1。Intel工程师没有注意这个缺陷,直到我在该手册之前的版本里发布了我的发现。

这个缺陷的后果是,一条大多数时间失败的分支指令将比大多数时间被采用的分支指令,误预测率高出3倍。在组织分支时,你可以将这个不对称性考虑在内,使得它们更多被采用。

BTB是前瞻的(P1)

P1里BTB机制是统计指令对,而不是单条指令,因此你必须知道指令如何组对(参考页),以分析一个BTB项保存在哪里。

用于任何控制指令的BTB项附加在前导指令对中的U-管道指令的地址上,(一条未成对指令算作一对)。例如:

;Example 3.1. Pentium 1 BTB mechansim

shreax, 1

movebx, [esi]

cmpeax, ebx

jbL

这里SHR与MOV组对,CMP与JB成对。JB L的BTB项附加在SHREAX, 1指令的地址上。。在遇到这个BTB项,并预测要采用该分支时,P1将从该BTB项读入目标地址,将L后的指令载入流水线。这发生在分支指令被解码前,因此,在这样做时,Pentium单纯依赖BTB中的信息。

在第一次执行时,指令偶尔成对(参考41页)。如果上面的指令没有成对,那么BTB项应该附加到CMP指令的地址上,在下一次执行,当指令成对时,这个项将是错误的。不过,在大多数情形里P1足够聪明,当还有未使用的成对机会时,不会制作BTB项,因此直到第二次执行才会得到一个BTB项,因而直到第三次执行,才会得到预测。(在很少见的情形里,其中每隔一条指令是单字节指令,可能在第一次执行就得到一个在第二次执行无效的BTB项,不过因为它所附着的指令将进入V-管道,它将被忽略且没有损害。如果附着到一条U管道指令地址上,BTB项是只读的)。

BTB项通过组值(set-value)来识别,它等于附着地址的0-5比特。比特6-31保存在BTB中作为一个标签。相隔64字节整数倍的地址具有相同的组值,相同的组值可以有不超过4个BTB项。

连续分支(consecutivebranches)

在一个跳转被误预测时,流水线得到冲刷。如果下一个执行指令对也包含一条控制转移指令,那么P1将不载入其目标,因为在冲刷流水线时它不能载入一个新目标。结果不管其BTB项的状态如何,第二条跳转指令被预测为失败。因此,如果第二个跳转也被采用,那么你将得到另一次惩罚。尽管第二个跳转BTB项的状态得到正确地更新。如果你有一长串控制转移指令,链中的第一个跳转被误预测,那么流水线将一直处于冲刷中,直到遇到非跳转指令对,你都将得到误预测。这最极端的情形是本身是跳转的循环:每次迭代都将得到误预测的惩罚。

这不是连续控制转移指令的唯一问题。另一个问题是,在一个BTB项及它所属控制转移指令间,可以有另一个分支指令。如果第一条分支指令跳转到别处,奇怪的事情可能发生。考虑这个例子:

          ; Example 3.2. P1 consecutivebranches

          shr eax, 1

          mov ebx, [esi]

          cmp eax, ebx

          jb L1

          jmp L2

L1:    mov eax, ebx

          Inc ebx

在JB L1失败时,我们将得到JMPL2的一个附着到CMPEAX, EBX地址上的BTB项。但当后面JBL1被采用时,将发生什么?在读JMPL2的BTB项时,处理器不知道下一对指令不包含跳转指令,因此它将事实上预测指令对MOVEAX, EBX / INC EBX跳转到L2。预测非跳转指令为跳转的惩罚是3时钟周期。JMP L2的BTB项将递减其状态,因为这适用于不跳转。如果我们一直跳到L1,那么JMPL2的BTB项将递减到状态1或0,这样直到JMPL2下一次执行,都没有问题出现。

预测非跳转指令跳转的惩罚,仅在预测跳转到L1时发生。在这个情形里,JBL1被误预测为跳转,流水线得到冲刷,L2的false目标没有载入,因此在这个情形中,我们将看不到预测非跳转指令跳转的惩罚,但JMPL2的BTB项被递减。

现在,假设我们以另一个跳转指令替换上面的INCEBX。这第三个跳转指令将使用与JMPL2相同的BTB项,预测错误的目标可能会有惩罚。

总而言之,连续跳转在P1中会导致以下问题:

·        当流水线被一个前导误预测跳转冲刷时,不能载入跳转目标。

·        BTB项被错误应用到非跳转指令,并预测跳转。

·        上述的次要后果是,错误应用的BTB项将被递减,可能导致所属跳转的后续误预测。因为这个原因,无条件跳转也会预测为失败。

·        两条跳转指令可能共享同一个BTB项,导致对一个错误目标的预测。

这一切可能带给你诸多惩罚,因此在P1中,你绝对应该避免在一个指令对中包含,紧跟着另一个可预测性差的控制转移指令或者其目标的跳转。另一个展示例子:

          ; Example 3.3a. P1 consecutivebranches

          call P

          test eax, eax

          jz L2

L1:    mov [edi], ebx

          add edi, 4

          dec eax

          jnz L1

L2:   call P

首先,我们可能注意到函数P从两个不同的位置交替调用。这意味着从P返回的目标将一直变化。结果,从P返回将总是被误预测。

现在,假设EAX是0。跳转到L2将不会载入其目标,因为误预测的返回导致流水线冲刷。接着,第二个CALLP也不会载入其目标,因为JZL2导致流水线冲刷。这里,我们处于由于第一个跳转被误预测,连续跳转使得流水线不断冲刷的状态。JZL2的BTB项保存在T的返回指令地址处。现在这个BTB项将错误应用于第二个CALLP之后,但这不会造成惩罚,因为误预测的第二个返回冲刷了流水线。

现在,让我们看一下如果EAX下一次有一个非零值会怎么样:因为冲刷,JZL2总是预测为失败。第二个CALLP在TESTEAX, EAX地址处有一个BTB项。这个项将被错误应用到MOV/ADD对,预测跳转到P。这导致一个冲刷,阻止JNZL1载入其目标。如果我们之前已经在这里,那么第二个CALLP将在DECEAX地址处有另一个BTB项。在循环的第二次与第三次迭代时,这个项也将错误应用到MOV/ADD对,直到它的状态递减到1或0。在第二次迭代时,因为来自JNZL1的冲刷,这不会导致惩罚,但在第三次迭代会。循环的后续迭代没有惩罚,但在它退出时,JNZL1被误预测。现在,冲刷将阻止CALLP载入其目标,假如不是因为CALLP的BTB项已经被多次错误应用所摧毁了。我们可以通过放置一些NOP分隔开所有连续的跳转来改进这个代码:

          ; Example 3.3b. P1 consecutivebranches

          call P

          test eax, eax

          nop

          jz L2

L1:     mov [edi], ebx

          add edi, 4

          dec eax

          jnz L1

L2:     nop

          nop

          call P

额外NOP的代价是2时钟周期,但它们节省更多。另外,JZL2现在移到U-管道,将误预测时的惩罚从4降到3。仅有的问题是从P返回总是被误预测。这个问题只能通过一个内联宏替换对P的调用来解决。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值