英特尔的x86 0x2E读取/ 0x3E的前缀分支预测实际使用?(Intel x86 0x2E/0x

2019-08-06 21:22发布

在最新的英特尔软件开发手册,它描述了两个操作码前缀:

Group 2 > Branch Hints

    0x2E: Branch Not Taken
    0x3E: Branch Taken

这些允许的跳转指令明确的分支预测(操作码一样Jxx

看完记得几年以前,在x86明确的分支预测基本上在GCCS分支prediciton内在的背景下,无操作。

我现在还不清楚,如果这86支提示是一个新的功能,还是它们基本上是空操作实践。

任何人都可以清除这个吗?

(即:是否GCCS分支预测功能产生这些与x86分支提示 - 做当前的Intel CPU,不是盲目的 - 当出现这种情况???)

更新:

我创建了一个快速测试方案:

int main(int argc, char** argv)
{
    if (__builtin_expect(argc,0))
        return 1;

    if (__builtin_expect(argc == 2, 1))
        return 2;

    return 3;
}

拆开以下几点:

00000000004004cc <main>:
  4004cc:   55                      push   %rbp
  4004cd:   48 89 e5                mov    %rsp,%rbp
  4004d0:   89 7d fc                mov    %edi,-0x4(%rbp)
  4004d3:   48 89 75 f0             mov    %rsi,-0x10(%rbp)
  4004d7:   8b 45 fc                mov    -0x4(%rbp),%eax
  4004da:   48 98                   cltq   
  4004dc:   48 85 c0                test   %rax,%rax
  4004df:   74 07                   je     4004e8 <main+0x1c>
  4004e1:   b8 01 00 00 00          mov    $0x1,%eax
  4004e6:   eb 1b                   jmp    400503 <main+0x37>
  4004e8:   83 7d fc 02             cmpl   $0x2,-0x4(%rbp)
  4004ec:   0f 94 c0                sete   %al
  4004ef:   0f b6 c0                movzbl %al,%eax
  4004f2:   48 85 c0                test   %rax,%rax
  4004f5:   74 07                   je     4004fe <main+0x32>
  4004f7:   b8 02 00 00 00          mov    $0x2,%eax
  4004fc:   eb 05                   jmp    400503 <main+0x37>
  4004fe:   b8 03 00 00 00          mov    $0x3,%eax
  400503:   5d                      pop    %rbp
  400504:   c3                      retq   
  400505:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  40050c:   00 00 00 
  40050f:   90                      nop

我没有看到2E或3E? 也许GCC有省略掉他们出于某种原因?

Answer 1:

这些指令的前缀对现代处理器(什么比奔腾4更新)没有影响。 他们只是成本的代码空间的一个字节,因此,不产生他们是正确的事情。

有关详细信息,请参阅昂纳雾的优化手册,特别是3。微架构: http://www.agner.org/optimize/

的“64和IA-32架构优化参考手册”不再提及它们在有关优化分支(3.4.1节)的部分: http://www.intel.de/content/dam/doc/manual/64 -ia-32体系结构优化-手册.pdf

这些前缀是Netburst架构的一个(无害)遗。 在全力以赴的优化,你可以用它们来对齐的代码,但是这对他们是很好的现在。



Answer 2:

海湾合作委员会是正确的,不产生前缀,因为他们一直在奔腾4处理器都没有效果。

__builtin_expect有其他影响,如在代码中移动预计不会代码路径从缓存热地点以外或内联的决定,所以它仍然是有用的。



Answer 3:

虽然奔腾4是实际尊重分支提示指令的唯一的一代,大多数的CPU确实有某种形式的静态分支预测 ,它可以用来实现同样的效果。 这个答案是有点切向原来的问题,但我认为这将是有价值的信息的人谁来到这个页面。

在英特尔优化指南和昂纳雾指南 (已在这里已经提到)都具有此功能的极好说明。


英特尔这样说一代的Core 2更新

使落空码以下的条件分支是一个目标前进的一个分支可能的目标

它向前跳的代码,以便有条件的分支预测为不采取,由静态预测算法。

这与什么GCC似乎使用已经产生一致__builtin_expect :所述“预期” return 1 / return 2码被放置在不被采用的路径从条件分支,这将被静态预测为不被采用。

另外:

没有历史的分支目标缓冲器分行使用静态预测算法预测:

  • 预计无条件分支才能作出。

  • 预测间接分支为不采取。

因此,在“预期”不被采用的路径,其中GCC已放置无条件jmp s到函数结束时,那些跳跃将静态预测为必要(即,不跳过)。

英特尔还表示:

使落空码以下的条件分支是一个落后的目标分支的目标不太可能

这在代码向后跳跃这样的条件分支被预测为采取,由静态预测算法。

据昂纳晴间多云,大部分的Pentium也按照这个算法:

上的PPro,P2,P3,P4和P4E,尚未见过的控制转移指令,或这不是在分支目标缓冲器,被预测落空,如果去转发,并且要采取如果去向后(例如,环)。 静态的预测花费的时间比这些处理器的动态预测更长的时间。

然而, 酷睿2家族(与奔腾M)具有完全不同的策略:

这些处理器没有使用静态预测。 该预测只是使随机预测第一次分支看出,这取决于恰好是分配给新的分支的BTB条目。 我们根本做跳跃或无妄的权预测的可能性为50%,但预测的目标是正确的。

因为这样做的AMD处理器明显:

分支预测不采取第一次看到。 一个分支是第一次服用后预测总是服用。 动态预测用于分支已经采取然后不采取之后。 分支提示前缀没有任何效果。

有要考虑的附加因素:CPU的一般喜欢以线性方式来执行,因此,即使正确地预测采纳分支往往比正确地预测不被采用的分支更加昂贵。



Answer 4:

英特尔®64和IA-32架构软件开发人员手册 - >第2卷:指令集参考,AZ - >第2章:指令格式 - >为保护模式,实地址模式2.1指令格式,和虚拟8086模式 - > 2.1 0.1指令前缀

用这些作为分支提示一些早期的微架构,但最近几代都没有,他们保留供未来使用提示。



文章来源: Intel x86 0x2E/0x3E Prefix Branch Prediction actually used?