SonicBOOM (BOOMv3) の論文をながめて思ったこと

5/29~6/4に行われたコンピューターアーキテクチャの国際会議、ISCA 2020 で開催されたワークショップ「CARRV」で発表されていた、Sonic BOOMの論文をながめて思ったことを書いておきます。

Figure 1 について

この手の図ってWikiChipでよく見る(例えば、 SkylakeSunnyCoveの図に非常に似ている)のですが、なんか業界の慣行なんでしょうか……?

分岐予測について

同じ ISCA 2020 の Industry Track で発表されていた IBM の分岐予測器の論文にも書かれていましたが、最近の商用プロセッサについている分岐予測器は、教科書的な分岐予測器とはかなり違う構成になっているようです。命令フェッチユニットは以下の物から構成されているようです。

  • 簡易分岐予測器
  • フェッチバッファ
  • 数サイクルかかるパイプライン化されている正確な分岐予測器
  • スナップショット付きの return address stack (RAS)

まず、簡易分岐予測器(L0 BTB*1)が毎サイクル動きます。

1サイクルで完了する簡易分岐予測器はたまに間違い、数サイクルかかる正確な分岐予測器が訂正するという事態が発生します。しかし、デコード速度よりフェッチ速度のほうが高いので、この問題は隠蔽されることが多いです。これを実現するため、フェッチユニットとデコードユニットの間にフェッチバッファが置かれます。

分岐予測器は、自分の出した予測に従って「過去の分岐の情報」を更新しつつどんどん未来を予測していきます。分岐予測ミスが発覚した場合、間違った予測に基づいて更新していた「過去の分岐の情報」を復帰しないと、狂った「過去の分岐の情報」に基づいて予測をすることになり、特に方向分岐予測器では、予測がボロボロになります。ここで、リターン命令に特化した補助分岐予測器であるRASは、そのような復帰をしなくても破滅的なことにはならない&復帰にかかるコストが方向分岐予測器より大きい、という理由から復帰しないことが多かったような気がしますが、最近はRASもちゃんと復帰するようにしたようです。

Short-forwards Branch optimizations について

非常に短いif節をコンパイルしたときに出現するような短距離前方分岐を、条件実行命令に変換するという最適化を内部で行うというものです。この最適化により、CoreMarkスコアが4.9から6.15に向上したと書かれています。

Figure 3 は「当てにくい分岐」の例だと思われますが、不適切な例です。 最大値を求めるループというのは、条件実行命令を使うとかえって遅くなる例として非常に有名です(条件分岐とcmovとmaxps)。 というのも、配列の中のほとんどの値は「現状最大値」より小さいので、not-takenと予測するのが精度よく当たるためです。 かえって遅くなる理由は、条件計算命令がクリティカルパスを伸ばすためです。

CoreMarkで大きな性能向上が得られる理由は、CoreMarkに巡回冗長検査 (Cyclic Redundancy Check, CRC) のコードが含まれるためです。 CRCの計算には完全ランダムな分岐が含まれ、分岐予測が当たらないため、条件分岐命令を使うとこのような性能向上が得られるのです。

ちなみに、CoreMarkをRV32Gの設定でgcc9.2.0を使ってコンパイルしたバイナリを使った場合、CoreMark/MHzは3.39×IPCに等しくなります。ここから算出すると、SonicBOOMの6.15CoreMark/MHzは、IPC=1.81ほどということになります(SonicBOOMはRV64GCですが、RV32Gと命令数が変わらないと仮定しました)。

*1:Column predictor(way予測器)が使われることもあります。n-wayセットアソシアティブキャッシュの何way目にありそうかを予測するものです。こう聞くと頭のおかしい予測器に聞こえますが、もっとも単純にはMRUポジションを予測するという方法があり、うまくいくらしいです。その場合、ダイレクトマップキャッシュ(L0)と(n-1)-wayセットアソシアティブキャッシュ(L1)の階層構造になっていることに相当します。