7

CPU を作成する場合、間違った分岐が選択されると、分岐予測が大幅に遅くなると思います。では、CPU 設計者は、単純に両方のブランチを実行し、どちらが選択されたかを確認してから 1 つを切断するのではなく、ブランチを選択するのはなぜでしょうか?

これは、短い数の命令内で 2 つまたは 3 つの分岐の深さしかできないこと、または並列ステージの数が途方もなく大きくなることを認識しています。このようないくつかの段階は意味がありませんか?物事を大幅にスピードアップし、少し複雑にする価値があるように思えます。

たった 1 つの深さのブランチでさえ、間違ったブランチによってほぼ半分の時間が費やされますよね?

それとも、このようにすでにある程度行われているのでしょうか?ブランチは通常、アセンブリに取り掛かるときに 2 つの選択肢から選択するだけですよね?

4

1 に答える 1

7

指数関数的にマシンを満たすことを恐れているのは正しいですが、その力を過小評価しています. 一般的な経験則では、動的コードで平均 20% 程度の分岐が予想されると言われています。これは、5 命令ごとに 1 つの分岐を意味します。今日のほとんどの CPU には、何百もの命令をフェッチして実行する深いアウトオブオーダー コアがあります。たとえば、Intel の Haswell を例にとると、192エントリの ROB があり、最大で 4 レベルの分岐を保持できます (その時点で、 ' 16 の「フロント」と 31 の「ブロック」があり、それぞれに 1 つの分岐分岐が含まれます - 各ブロックに 5 つの命令があり、ROB がほぼいっぱいになり、別のレベルがそれを超えると仮定します)。その時点では、有効な深さの ~20 命令までしか進行していません。

3 レベルの分岐で分岐したい場合は、8 つの並列コンテキストが存在しないことを意味し、それぞれが先に実行できるエントリは 24 しかありません。そして、それは、作業の 7/8 をロールバックするためのオーバーヘッド、状態を保存するすべてのハードウェア (数十あるレジスターなど) を複製する必要性、および他のリソースをあなたのように 8 つの部分に分割する必要性を無視する場合のみです。 ROBで行いました。また、複雑なバージョン管理、転送、一貫性などを管理する必要があるメモリ管理は含まれていません。

消費電力のことは忘れてください。無駄な並列処理をサポートできたとしても、各パスで数個以上の命令を進める前に、リソースを薄く分散させると、文字通り窒息してしまいます。

ここで、単一のブランチに分割するというより合理的なオプションを調べてみましょう。これは、ハイパースレッディングのように見え始めています。コア リソースを 2 つのコンテキストに分割/共有します。この機能には確かにパフォーマンス上の利点がありますが、それは両方のコンテキストが非投機的であるという理由だけです。現状では、一般的な見積もりは、ワークロードの組み合わせに応じて、2 つのコンテキストを次々に実行した場合の約 10 ~ 30% であると考えています (AnandTech によるレビューの数値はこちら)。次々にタスクを実行しますが、そのうちの 1 つの結果を破棄しようとしているときはそうではありません。ここでモード切り替えのオーバーヘッドを無視しても、30% 増加して 50% を失うだけです。意味がありません。

一方、分岐を予測し (現在の最新の予測子は平均で 95% 以上の成功率に達する可能性があります)、予測ミスのペナルティを支払うオプションがあります。分岐より前の命令は、分岐がクリアされた後に実行される可能性があります。ほとんどの OOO マシンはそれをサポートしています)。これにより、完全に故障したエンジンが自由に動き回り、潜在的な深さまで推測し、ほとんどの場合正しくなります。ここでの作業の一部をフラッシングする確率は幾何学的に減少します (最初のブランチの後は 95%、2 番目のブランチの後は ~90% など) が、フラッシュのペナルティも減少します。これは、1/n のグローバル効率 (n レベルの分岐の場合) よりもはるかに優れています。

于 2014-10-20T17:57:21.767 に答える