1

分岐予測について読んでいましたが、分岐予測子が「投機的に」あらゆる種類の命令を実行するかどうか疑問に思っています。特に、例えばハードウェアと通信するかどうかは疑問です。

次のようなものがあるとします。

while (true) {
   if (condition)
      SendPacketOverNetwork()
   DoSomethingElse()
}

(アセンブリ レベルでは、if の後の最初の命令が割り込みを発生させるか、ハードウェアと通信します)。この場合、分岐予測子がたまたま「間違っていると推測」するとどうなるでしょうか? これができない場合、なぜですか?分岐予測子はどのような命令を実行しますか? 分岐予測子の機能を誤解していますか?

4

1 に答える 1

5

まず第一に、分岐予測子は何も実行せず、フェッチして実行する次の命令を CPU に伝えるだけです。次に、CPU は次の一連の命令をフェッチしてパイプラインに挿入し、それらの実行を開始します。

外部世界に影響を与えるすべての操作 (つまり、コアの外で観察可能) は、それぞれの命令がリタイアしてコミットされた後にのみ実行されます。CPU が投機的状態の漏洩を防ぐためにコアの外部に専用のバッファリングを備えている場合、いくつかの小さな例外が存在する可能性がありますが、結果は同じです。操作が内部で実行されたとしても、その時点までは観察できません。それがコミットされている場所。メモリへのストア、ポートアウト、ブレークポイント、またはその他の監視可能なアクションがすべて含まれます。

分岐の予測ミスが発生すると、投機的な状態がフラッシュされ、予測ミスの分岐よりも新しいすべての操作がロールバックされるなど、マシンの偽の結果がすべてロールバックされます (通常は順序付けバッファーによって管理される順序が正しくない CPU で)。もちろん、正確な詳細は実際のマイクロアーキテクチャに依存します。コミットは順序どおりに実行されるため (実行が順不同で行われる場合でも)、収束点として機能します。予測を誤った分岐の実行は、パイプラインのその時点よりも前に行われる必要があります。より若い命令の引退とコミットに (それらはしばしばそのブランチの「影にある」と見なされます)。その結果、外部から観測可能な操作は、予測されなかった分岐よりも古い場合を除き、まだ実行されていません。

例(より興味深いケースであるため、故障したマシンで):

op1   |         exec          retire     
op2   |    exec                 retire    
branch|            exec           retire   
op3   |   exec                      retire 
op4   |          exec                 retire
store |                                 retire    dispatch
        ---------------------------> Time

ブランチが実行時に予測が間違っていることを発見した場合、次の命令は、リタイア/コミットまたはパイプに沿った後の何か (新しいストアの実行を含む) の前にフラッシュされることが保証されます。はるかに単純なインオーダー マシンでは、実行自体が順序付けられるため、新しい命令の実行よりも前に分岐が実行されます (分岐の解決がわかります)。

于 2014-05-15T14:21:31.530 に答える