条件を確認する必要がある場合、分岐予測はどのように機能しますか?


30

私はhttps://stackoverflow.com/q/11227809/555690から分岐予測に関する一般的な答えを読んでいたのですが、私を混乱させる何かがあります:

  • あなたが正しく推測した場合、それは続けます。
  • あなたが間違っていると推測した場合、船長は停止し、後退し、スイッチを入れるように叫びます。その後、他のパスで再起動できます。

毎回正しいと思うなら、、列車は停止する必要はありません。

間違った推測をしすぎると、列車は停止、バックアップ、再起動に多くの時間を費やします。

しかし、これは私が得られないものです:あなたの推測が正しかったか間違っているかを知るには、とにかく状態チェックを行わなければなりませ。どちらの方法でも同じ条件チェックを実行している場合、分岐予測はどのように機能しますか?

私が言おうとしているのは、とにかく同じ条件チェックを行っているので、分岐予測はまったく分岐予測がないこととまったく同じではないということです。(明らかに私は間違っていますが、わかりません)


1
このwiki記事は、それを説明するのにかなり良い仕事をしています。
エンダーランド

8
最新のCPUはパイプライン化されており、同時にいくつかのことを実行できます。したがって、正しく推測したかどうかを判断しながら、推測の実行を開始できます。推測が正しければ、パイプラインは実行を続けます。間違った推測では、パイプラインは破棄され、「正しい答え」ポイントから実行が再開されます。
マークスペース

2
関連資料:パイプライン。ここであなたの質問に答えているので、そのSOの質問で受け入れられた答えを読み直すこともお勧めします。

回答:


19

もちろん、状態は毎回チェックされます。しかし、チェックされるまでには、CPUパイプラインに到達しています。それまでの間、他の命令もパイプラインに入り、さまざまな実行段階にあります。

通常、条件の直後に条件分岐命令が続き、条件がTRUEと評価されると分岐するか、条件がFALSEと評価されると分岐します。これは、条件がTRUEまたはFALSEに評価されるかどうかに応じて、条件命令と分岐命令の後にパイプラインにロードされる命令の2つの異なるストリームがあることを意味します。残念ながら、条件命令と分岐命令を読み込んだ直後、CPUは条件がどのように評価されるかをまだ知りませんが、それでもパイプラインへの読み込みを続けなければなりません。そのため、条件の評価対象に関する推測に基づいて、2つの命令セットのいずれかを選択します。

後で、条件命令がパイプラインを上に移動するときに、評価する時間になります。その時点で、CPUはその推測が正しかったか間違っているかを調べます。

推測が正しいことが判明した場合、ブランチは正しい場所に行き、正しい命令がパイプラインにロードされました。推測が間違っていることが判明した場合、条件分岐命令の後にパイプラインにロードされたすべての命令は間違っていたため、破棄する必要があり、命令のフェッチは正しい場所から再度開始する必要があります。

修正

StarWeaverのコメントに応えて、単一の命令を実行するためにCPUがしなければならないことのアイデアを与えるには:

MOV AX,[SI+10]人間が「SIに10を加えた単語をAXにロードする」と私たちが単純に考えているような単純なものを考えてください。おおよそ、CPUは次のことを行う必要があります。

  1. PC(「プログラムカウンターレジスタ」)の内容をアドレスバスに出力します。
  2. データバスから命令オペコードを読み取ります。
  3. PCをインクリメントします。
  4. オペコードをデコードして、それをどう処理するかを把握します。
  5. PCの内容をアドレスバスに出力します。
  6. データバスから命令オペランド(この場合は10)を読み取ります。
  7. PCをインクリメントします。
  8. オペランドとSIを加算器に送ります。
  9. 加算器の結果をアドレスバスに出力します。
  10. データバスからAXを読み取ります。

これはなんと10ステップです。これらのステップの一部は、パイプライン化されていないCPUでも最適化されます。たとえば、CPUは次のステップと並行してほとんど常にPCをインクリメントします。PCは非常に特殊なレジスタであるため、簡単に実行できます他のジョブに使用されることはないため、この特定のレジスタにアクセスするためにCPUの異なる部分間で競合する可能性はありません。しかし、それでも、このような単純な命令には8つのステップが残っています。CPUに代わって、ある程度の高度化をすでに想定していることに注意してください。たとえば、結果が読み取られる前に実際に加算を実行する加算器、

次に、のようなより複雑なアドレス指定モードMOV AX, [DX+SI*4+10]MUL AX, operand、CPU内で実際にループを実行して結果を計算するようなはるかに複雑な命令が存在することを考慮してください。

したがって、ここでの私のポイントは、「原子レベル」のメタファーはCPU命令レベルには適していないということです。実際のロジックゲートレベルまでさかのぼりたくない場合は、パイプラインステップレベルに適している場合があります。


2
ええと、私を含めて人々がこれを理解することについての問題の一部は、単一の命令の部分的な知識しか持っていないCPUを想像することは(とにかく)非常に難しいということだろうか?または、「ピザベルトオーブンを通過する」という半分の完成した指示を持っていることは、少なくとも、私にとっては、エレクターセットと金属旋盤レベルの間で作業をするのに慣れていると、原子スケールに移行するように感じます。
StarWeaver

1
@StarWeaverあなたのコメントが気に入ったので、それに答えるために答えを修正しました。
マイクナキス

1
うわー、素敵な説明。言葉をより便利な場所に移動するだけでどれだけのことになるのかを忘れがちです。私はまだCPUをベルト駆動のピザオーブンのセットとして視覚化しています:3。
StarWeaver

OPによってリンクされたStack Overflowの質問 -おそらく100万人以上のプログラマーに「分岐予測」が存在するというこれまで知らなかった事実を紹介した130万のビューを持つ質問Javaの例を示していることを心に留めておく価値があります。Javaのような言語が私たちに提供する抽象化のレベルで働くことに慣れている私のような人々にとってMOV AX,[SI+10]は、「単純」ではなく、異質でさえあります。今日、ほとんどのプログラマーはアセンブリを作成したことがありません。私たちはそれを何も意味するものとして「単純に」考えていません。
マークアメリー

@MarkAmeryよく、わかりました。「私たち人間」とは、「アセンブリをあえて書く人間」という意味です。アセンブリ言語のプログラマでさえ、パイプラインを常に考えているわけでも、まったく考えていないということも指摘されています。
マイクナキス

28

GPSのないロードトリップのようなものだと考えてください。交差点に来て、曲がる必要があると思いますが、完全にはわかりません。だから、あなたはターンを取りますが、あなたの乗客に地図をチェックするよう頼みます。たぶん、あなたはあなたがどこにいるかについて議論し終えるまでに道を3マイル進んでいるでしょう。あなたが正しかったなら、あなたは、あなたが止まる前に、そして曲がる前に議論した場合よりも3マイル遠くにいます。あなたが間違っていた場合は、振り向く必要があります。

CPUパイプラインも同様に機能します。彼らが状態をチェックできる頃には、彼らはすでに道を進んでいます。違いは、彼らは3マイルを後退させる必要はありません、彼らはただスタートを失うだけです。つまり、試しても害はありません。


2
この説明は簡潔です。
sharptooth

2

私の理解では、チェックする必要のある条件が高価なまたは進行中の何かの結果を必要とする場合、分岐予測は最も便利です。

アウトオブオーダー実行のようなもので、分岐予測を使用して、パイプライン内の空のスポットの充填を開始できます。そうしないと、CPUは使用できなくなります。何らかの理由でパイプラインにアイドルサイクルが存在しない状況では、はい、分岐予測にゲインはありません。

ただし、ここで重要なのは、CPUが条件自体をまだ評価できないため、予測されたブランチの1つで作業を開始していることです。


1

ショートフォーム:

一部のCPUは、古い命令を完了する前に新しい命令の処理を開始できます。これらは、分岐予測を使用するCPUです。

擬似コードの例:

int globalVariable;
int Read(int* readThis, int* readThat)
{
    if ((globalVariable*globalVariable % 17) < 5)
       return *readThis;
    else
       return *readThat;
}

上記のコードは条件をチェックし、結果に基づいて、メモリ位置にaddThis保存されている値またはに保存されている値を返す必要がありますreadThat。分岐予測で条件がになると予測されるtrue場合、CPUはステートメントaddThisを評価するために必要な計算を行いながら、メモリ位置に保存された値をすでに読み取りますif。これは簡単な例です。


1

はい、どちらの方法でも条件がチェックされます。ただし、分岐予測の利点は、条件チェックの結果を待つ代わりに作業を行えることです。

エッセイを書く必要があり、トピックAまたはトピックBについて書かれているとします。以前のエッセイから、先生はトピックAがBよりも好きで、より頻繁に選択することがわかります。彼の決定を待つ代わりに、最初のトピックに関するエッセイを書き始めることができます。現在、2つの可能な結果があります。

  1. あなたは間違ったトピックについてエッセイを始め、あなたがこれまでに書いたものを落とさなければなりません。他のトピックについて書き始める必要があり、それはあなたが待っていたのと同じ時間の努力です。
  2. あなたは正しく推測し、あなたはすでに仕事を終えました。

最近のCPUは、IO応答または他の計算の結果を待っているため、ほとんどの時間アイドル状態です。この時間は、将来の作業に使用できます。

このアイドル時間に何をしているのかを無視しなければならない場合でも、プログラムが選択するパスを推測できる場合は、より効果的です。そして、最新のCPUにはこの機能があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.