負の方向のレイテンシ

Blackfinの演算命令は、原則として1サイクルで演算を完了します。したがって、演算命令の結果を直後に参照してもストールは発生しません。例えば、

r0.L = r1.L + r2.H;
r4.L = r0.L + r3.H; // 前の演算結果を参照している

といった命令を実行してもストールは発生しません。しかしこれには例外があります。乗算器を使う命令はマルチサイクル命令になっているのです。つまり、

r0.H = r1.H * r2.L ;

などといった乗算命令には2サイクルかかります*1。面白いのはこの結果発生するのが負の方向のレイテンシだということです。
直感的に考えると、2サイクルかかる演算の結果を利用するとストールが発生する気がします。例えば、

r0.H = r1.H * r2.L;
r4.H = r0.H + r3.H;  // 乗算結果を参照している

といった命令列を実行すると、乗算の後に1サイクルのストールが発生してレイテンシを吸収した後加算を実行すると思えます。しかし、Blackfinではこうなりません。上の例ではストールは発生しません。Blackfinの場合、負の方向に*2ストールが発生するのです!例えば、

r0.H = r1.H + r2.H;  // 乗算に参照されている
r4.H = r0.H * r3.L;

のように、乗算命令が加算命令の結果を参照すると、加算命令の後にレイテンシが発生します。加算は1サイクルで完了するにもかかわらずです。この結果、一般的なプロセッサではレイテンシの大きな命令が、後続の命令を待たせるのに対して、Blackfinではレイテンシの大きな命令が前の命令に遠慮して後ずさりするような形になります。
こうなる理由は実に簡単です。われわれは実行サイクルの異なる命令は可変長パイプラインで実装すると考えがちですが、Blackfinでは固定長パイプラインなのです。そうして、加算命令のように1サイクルで実行可能な命令は、演算パイプラインの中で1サイクル休んでから実行しています。この結果、乗算命令は他の命令より余計に準備サイクルが必要だと言うことです。

*1:ただしスループットは1。つまりパイプライン実行によって毎サイクル積を出力できる

*2:蛇足だが「負の方向のストール」などと言うのはもちろん言葉の遊びであって、実際には後述するようにセットアップ時間によるストールが発生している