32

最新の Intel ソフトウェア開発マニュアルでは、次の 2 つのオペコード プレフィックスについて説明しています。

Group 2 > Branch Hints

    0x2E: Branch Not Taken
    0x3E: Branch Taken

これらにより、Jump 命令 (のようなオペコードJxx)の明示的な分岐予測が可能になります。

数年前に、x86 での明示的な分岐予測は、gccs の分岐予測組み込み関数のコンテキストでは基本的にノーオペレーションだったという記事を読んだことを覚えています。

これらの x86 ブランチ ヒントが新しい機能なのか、それとも実際には基本的にノーオペレーションなのかは不明です。

誰でもこれをクリアできますか?

(つまり、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 がそれらを除外したのではないでしょうか?

4

4 に答える 4

33

これらの命令プレフィックスは、最新のプロセッサ (Pentium 4 よりも新しいもの) には影響しません。それらは 1 バイトのコード空間を消費するだけなので、それらを生成しないのは正しいことです。

詳細については、Agner Fog の最適化マニュアル、特に 3. マイクロアーキテクチャ: http://www.agner.org/optimize/を参照してください。

「インテル® 64 および IA-32 アーキテクチャー最適化リファレンス・マニュアル」では、ブランチの最適化に関するセクション (セクション 3.4.1) でそれらについて言及されていません: http://www.intel.de/content/dam/doc/manual/64 -ia-32-architectures-optimization-manual.pdf

これらのプレフィックスは、Netburst アーキテクチャの (無害な) 遺物です。全面的な最適化では、それらを使用してコードを整列させることができますが、最近ではそれだけで十分です。

于 2013-01-15T09:35:37.497 に答える
15

gccは、Pentium 4以降のすべてのプロセッサに影響を与えないため、プレフィックスを生成しないのが正しいです。

ただし__builtin_expect、予期しないコードパスをコード内のキャッシュホットな場所から移動したり、決定をインライン化したりするなど、他の効果もあるため、それでも便利です。

于 2013-01-15T09:45:27.123 に答える
12

Pentium 4 は分岐ヒント命令を実際に尊重する唯一の世代ですが、ほとんどの CPU には何らかの形式の静的分岐予測があり、これを使用して同じ効果を得ることができます。この回答は元の質問とは少し関係がありますが、このページにアクセスした人にとっては貴重な情報になると思います。

Intel 最適化ガイドAgner Fog のガイド(既にここで言及されています) の両方に、この機能に関する優れた説明があります。


Intel は、Core 2 よりも新しい世代について次のように述べています。

条件付き分岐に続くフォールスルー コードが、前方ターゲットを持つ分岐のターゲットになる可能性が高くなります。

そのため、コード内で前方にジャンプする条件分岐は、静的予測アルゴリズムによって、取られないと予測されます。

これは、GCC が を使用して生成したように見えるものと一致しています。__builtin_expect「期待される」コードは、条件付き分岐からの非取得パスに配置され、非取得として静的に予測されます。return 1return 2

さらに:

ブランチ ターゲット バッファーに履歴がないブランチは、静的予測アルゴリズムを使用して予測されます。

  • 取られる無条件分岐を予測します。

  • 間接分岐が行われないことを予測します。

そのため、GCC が関数の最後に無条件の s を配置した「予期される」不採用パスではjmp、これらのジャンプは静的に採用される (つまり、スキップされない) と予測されます。

インテルは次のようにも述べています。

条件付き分岐に続くフォールスルー コードが、後方ターゲットを持つ分岐のターゲットになる可能性が低いようにする

そのため、静的予測アルゴリズムによって、コード内で逆方向にジャンプする条件分岐が実行されると予測されます。

Agner Fog によると、ほとんどのPentiumもこのアルゴリズムに従っています。

PPro、P2、P3、P4、および P4E では、前に見られなかったコントロール転送命令、または分岐ターゲット バッファーにないコントロール転送命令は、順方向に進むと失敗し、逆方向に進むと取得されると予測されます。 (例: ループ)。これらのプロセッサでは、静的予測は動的予測よりも時間がかかります。

ただし、Core 2ファミリ (および Pentium M) には、まったく異なるポリシーがあります。

これらのプロセッサは静的予測を使用しません。予測子は、新しい分岐に割り当てられた BTB エントリに何が起こるかに応じて、分岐が初めて見られたときに単純にランダムな予測を行います。ジャンプするかジャンプしないかを正しく予測する確率は 50% ですが、予測されたターゲットは正しいです。

AMDプロセッサと同様に、明らかに:

分岐は、最初に表示されたときに取得されないと予測されます。分岐は、最初に実行された後に常に実行されると予測されます。動的予測は、分岐が実行されて実行されなくなった後にのみ使用されます。分岐ヒントのプレフィックスは効果がありません。

考慮すべき追加の要因が 1 つあります。CPU は通常、直線的に実行することを好みます。そのため、正しく予測された実行済み分岐であっても、正しく予測された実行されなかった分岐よりもコストがかかることがよくあります。

于 2015-10-25T07:20:01.570 に答える