後藤弘茂のWeekly海外ニュース

相対的に大人しい設計のAMD次世代CPU「ZEN」の浮動小数点/SIMDユニット

ZENの浮動小数点/SIMDパイプは4命令並列

 AMDは“ZEN”マイクロアーキテクチャにおいて、浮動小数点/SIMDパイプラインも完全に再設計した。ZENの浮動小数点/SIMD(Single Instruction, Multiple Data)演算ユニットは、128-bit幅SIMDの乗算&積和算ユニット(MUL/FMAD)と、128-bit SIMDの加算ユニット(ADD)のペアが2セットの、計4パイプとなっている。合計で128-bit 乗算&積和算が2ユニット、加算が2ユニットで、最大4命令/サイクルの命令発行が可能だ。ディスパッチャからの出力も、最大4マイクロOPとなっている。128-bitと言っても、もちろんSIMDで、32-bit単精度なら4-way、64-bit倍精度なら2-wayとなる。

 “Bulldozer”アーキテクチャでは、浮動小数点/SIMD演算ユニットは合計で4つ。128-bitの積和算ユニット(FMAD)が2つと、128-bitのSIMD整数演算ユニットが2個で、命令発行は4ポートだった。Bulldozerを改良した“Steamroller”では、FPユニット部の設計に手が入り、128-bitの積和算(FMAD)とSIMD整数の統合パイプと、128-bit積和算ユニット、28-bitのSIMD整数演算とシャッフルのコンバインパイプの3パイプ構成、3命令発行となっていた。

AMDのCPUマイクロアーキテクチャの流れ
AMDのZENマイクロアーキテクチャの全体像

 ZENでは、SIMDの乗算と加算を並列に実行できるようになった。そのため、乗算と加算が並列する場合は、スループットが前世代より上がる。設計的には、相対的にコストが安い加算ユニットのパイプを加えている。積和算は128-bitで2パイプで、積和算時は加算はできないので、1サイクルに2命令、積和算なので4オペレーション、32-bit単精度浮動小数点演算なら128-bit SIMDで4並列であるため、16オペレーション/サイクルとなる。

 浮動小数点レジスタは、Bulldozerの物理FPレジスタは160レジスタ(128-bit幅)で、ZENも160レジスタと変わらない。Piledriverは176レジスタだったので、物理レジスタ数は減ったことになるが、実行レイテンシとも関係するので、まだ比較ができない。

ZENマイクロアーキテクチャ

CPUのベクタユニットの思想が異なるIntelとAMD

 Intelアーキテクチャと比較すると、Intelの現行アーキテクチャは、256-bitの積和算ユニット(FMAD)を2ユニット備える。そのため、積和算のスループットでは、Intelの方が2倍高くなる。しかし、これは256-bit SIMDを使う場合に限定される。物理レジスタリソースは、Skylakeが168レジスタに対してZENが160だ。

 IntelとAMDは、CPUでのショートベクタ演算についての考え方が大きく異なっている。Intelはショートベクタを広げることに熱心だ。SSEの128-bitベクタからAVXで256-bitベクタに拡張し、MIC (Many Integrated Core)アーキテクチャの“Knights”系メニーコアCPUでは、512-bitベクタを採用した。そして、Knightsの命令セットは、命令フォーマットを変更し、「AVX-512」として「Xeon Phi x200 (Knights Landing)」に実装しただけでなく、SkylakeアーキテクチャのXeonブランドのサーバーCPUにも採用する。

IntelとAMDのマイクロアーキテクチャ比較

 短く言えば、Intelはx86/x64 CPUのSIMD命令を拡張して、よりベクタ長を長くし続けようとしている。現在のIntel CPUの256-bitのSIMDユニットは、512-bit命令のサポートを想定してのものだ。AVX-512では、GPUと同じようにプレディケーションによるコントロールフロー制御もできる。つまり、IntelはGPUのようなベクタ演算を、CPUの内部に取りこもうとしている。

IntelのパフォーマンスCPUとKnights Landing

 それに対してAMDは、CPUのベクタは128-bit幅で十分と考えている印象が強い。32-bit単精度で4-wayまでが、CPUの命令ストリームで効率的に扱うことができる粒度で、それ以上にベクタを広げても効果が薄いと考えていると見られる。そのため、SIMDユニットは128-bit幅までに留める。ワイドなベクタ演算は、GPUコア側で実行すれば良いというのが、AMDのヘテロジニアスコンピューティングの発想だ。

積和算パイプは加算パイプからレジスタポートを借用

 AMDの公式な図では、ZENの浮動小数点演算パイプは、乗算ユニット(MUL)と加算ユニット(ADD)がそれぞれ2つずつとなっている。しかし実際には、乗算パイプには積和算ユニットが組み込まれている。FMAまたはFMADと呼ばれる融合型積和演算については、積和算ユニットで実行される。乗算ユニットと加算ユニットを合わせて使う方式ではない。

 「積和算ユニットは乗算パイプに含まれている。(乗算ユニットと加算ユニットを合わせて使うのではなく)積和算用のユニットがある」(Mike Clark氏, Senior Fellow, AMD)

 そのため、原理的には、積和算時にも2つ(乗算と加算)のパイプを同時に動かすことができる。しかし、実際には積和算と加算は同時に行なうことができない。これはレジスタファイルのリードポートの制約によるものだという。

ZENの浮動小数点演算ユニット部

 ZENの4つの浮動小数点/SIMD演算ユニットは、それぞれ2つのレジスタリードポートを備える。1サイクルに、各ユニットで2つのソースオペランドのリードが可能だ。しかし積和算時には、3つのソースオペランドをリードする必要がある。

 「積和算では、3つの(ソース)オペランドが必要だ。レジスタファイルから読み出す場合、リードポートが足りなくなる。そのため、ちょっとしたトリックを使っている。積和算時には、加算パイプからレジスタファイルリードポートを1つ借用している。積和算時には、加算ユニットは使っていないため、加算ユニット自体は空いている。しかし、加算ユニットにはレジスタリードポートが1つしか残らない。そのため、加算(の命令発行)はスケジューラがブロックする」(Mike Clark氏, Senior Fellow, AMD)

 つまり、演算ユニット自体は乗算&積和算ユニット(MUL/FMAD)と加算ユニット(ADD)で分離されているが、レジスタリードポート数が限られているため、積和算と加算は同時には実行できない。FPレジスタファイル全体では、128-bitのリードポートが各ユニット2つずつの、合計8ポートということになる。

ZENの浮動小数点/SIMD演算ユニットとレジスタポートの関係

256-bit命令は2個の128-bit SIMDマイクロOPに分解して実行

 x86/x64系のAVX2命令には、256-bit幅のSIMD演算命令がある。AMDもAVX2をサポートしているが、これはマイクロOPレベルで分解して実行する。

 「256-bit命令は2つのピースに分解して、それぞれ独立して実行する。128-bitの演算ユニットを2つ結合させて実行するのではない。2つの128-bitオペレーションは、完全に独立したマイクロOPとなる。この2つのマイクロOPをアウトオブオーダで実行することもできる。リタイヤする時に一緒にするが、それまでは独立する」(Mike Clark氏, Senior Fellow, AMD)

 256-bit AVX命令は、ディスパッチステージで細粒度のマイクロOPレベルに分解され、個別の128-bitマイクロOPとしてスケジュールされる。マイクロOPに分解する段階で、2個または4個(オペランドにメモリが含まれる場合)の128-bit SIMDマイクロOPに分解されると見られる。レジスタもそれぞれが128-bitレジスタを使う。命令リタイヤは256-bit命令としてなされる必要があるが、それまでは、2つの128-bit演算マイクロOPは、依存性に問題がない限りアウトオブオーダで実行される。

スケジューリングをチェックしないキューを設ける

 ZENの浮動小数点ユニット部では、マイクロOPのキューが2段階になっている。「NSQ (Non-Scheduling Queue)」と「スケジューラキュー(Scheduler Queue)」だ。従来はスケジューラのキューだけだったのが、新たにNSQが加えられた。

 スケジューラキューは、各実行ユニットに対して、マイクロOPsを発行するまで待機させスケジューリングするキュー。アウトオブオーダのスケジューラとして一般的なものだ。リソースがアベイラブルになると、スケジューラキューからマイクロOPが実行ユニットに発行される。

ZENの実行エンジン

 それに対して、前段のNSQに入っている段階では、FPマイクロOPをスケジュールすることはできない。言い換えれば、単なるマイクロOPのバッファだ。しかし、NSQにFPマイクロOPが待機している間に、整数ユニット側に発行された、ほかのマイクロOPが実行される。相対的にレイテンシの長いロードマイクロOPが実行されている間に、FPマイクロOPはNSQからスケジューラキューへと移る。そして、FPマイクロOPが演算パイプにディスパッチされる頃には、オペランドのデータがレジスタにロードされているという。

 2段階のキューとすることで、ZENではスケジューリングリソースを節約することができる。別な見方をすると、キューイングの前半はリソースのチェックなどのスケジューリングをせずに、ロードレイテンシを隠蔽するためだけにマイクロOPをバッファする形に変えた。これによって、スケジューリングのリソースを抑えながら、キューイングを効率的にできるように変更した。整数と浮動小数点演算のキューイングのバランスが取れるように調整したとAMDは説明する。

 ZENの浮動小数点/SIMD演算ユニット部の特徴は、リソースを抑えながら高い効率を発揮できるように設計されている点だ。Intelが256-bitの積和算エンジンを2ユニット搭載して、リソースを大きく浮動小数点/SIMDに割いたのとは対照的だ。GPUコアとのヘテロジニアスコンピューティングを前提としたAMDと、CPUコアにGPU的なアプローチを取りこむ方向へと進むIntelとの違いが明瞭に見える。