、あなたは以下のアセンブリコードを使用している場合:x86-64パイプラインがJMP RAXのような間接ジャンプで停止しますか? x86-64では
MOV RAX, (memory address)
JMP RAX
は(RAXで終了するMOVを待つ)ブランチを実行する前に、パイプラインのストールをい、またはそれは条件付きのようなパイプラインをフラッシュしますブランチ?
、あなたは以下のアセンブリコードを使用している場合:x86-64パイプラインがJMP RAXのような間接ジャンプで停止しますか? x86-64では
MOV RAX, (memory address)
JMP RAX
は(RAXで終了するMOVを待つ)ブランチを実行する前に、パイプラインのストールをい、またはそれは条件付きのようなパイプラインをフラッシュしますブランチ?
最新の80x86 CPUの場合、静的予測(より良い予測を行うために使用する履歴はありません)と動的予測(使用可能な過去の実行の履歴があります)があります。
静的予測の場合、CPUはJMP RAX
の直後の命令で実行を続行すると予測します。どのCPUが(Jc
ブランチではなく)JMP RAX
の動的予測を使用しているかは完全にはわかりません。静的予測をオーバーライドするものについては、
CPUに予測されたターゲットアドレスがあれば、予測されたかどうかを知るまで投機的に実行されます。それが正しいと予測すれば、それはすべての仕事を維持し、JMP RAX
はほとんどまたはまったく費用がかかりません。
CPUが間違って予測した場合、他のブランチの誤った予測(投機的に実行されたすべての処理を破棄し、正しいRIPでフェッチ/デコードする)には違いはありません。
JMP RAX
が予測できない場合や、ジャンプのターゲットになる可能性があまりにも低い場合は注意してください。インテルはジャンプの直後にPAUSE
またはUD2
を入れて、不要な投機的実行を防ぐことを推奨します。この場合、CPUはストールします(正しいジャンプ先が見つかるまで何もしないでください)。
MOV RAX, ..
はできるだけ早く実行されるようにして、できるだけ早くジャンプのターゲットがわかるようにしてください。ジャンプや投機的実行に要する時間を最小限に抑えます。間違ったこと。
静的にnot-takenを予測することは、無条件の間接的なブランチに対して意味をなさない。 IDKどのブランチターゲットバッファ予測が利用可能でない場合に何が起こるのですか?しかし、どのCPUも、分岐ターゲットが次の命令であるという前提で、以下の命令を投機的に実行することは疑う。おそらく、 'pause'や' ud2'が推奨されるなら、私はそれについて間違っています。場合によってはud2を使って投機的実行をブロックすることについての読書を覚えていますが、どこを忘れてしまったでしょうか。 –
現代のx86 CPUは、Atomのような低電力設計でさえも、間接分岐の分岐ターゲットを予測するための少なくともいくつかの能力を備えています。 SnBファミリのような大規模な設計では、間接分岐ターゲットアドレスの短いパターンを認識することさえできます。 –
@PeterCordes:インテルの最適化ガイドのほとんどのバージョンでは、次のようなことが言います(2012年4月版から「E.1ルール13」とほぼ同じです): "間接分岐が存在する場合、あるいは、間接分岐が共通であるが予測できない場合は、UD2命令で間接分岐をたどり、プロセッサがフォールスルーパスをデコードするのを停止します。もちろん、ガイド全体で詳細が提供されています(コメント欄の文字数制限に合わせて凝縮されています) – Brendan
誤って予測された条件分岐であっても、最新の設計ではパイプラインを完全にフラッシュする必要はありません。パイプラインは、誤って予測された分岐の前に命令上で行ったすべての正しい作業を維持することができます。これはIntel SnBファミリにも当てはまりますが、おそらくCore2にも当てはまります。私は忘れていますが、[Agner Fogのミクロンガイドは言うかもしれません](http://agner.org/optimize) –