最新の 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 がそれらを除外したのではないでしょうか?