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

ここまで見えたAMDの次期CPU「Bulldozer」



●2コアを統合したBulldozer Module

 同じAMDの32nmプロセス世代のCPUでも、新アーキテクチャ「Bulldozer(ブルドーザ)」ベースの「Orochi(オロチ)」と、旧アーキテクチャ「K10(Hound)」ベースの「Llano(ラノ)」を比べると大きな違いが見える。LlanoにあるGPUコアがOrochiにないのはもちろんだが、OrochiではCPUコアのモジュールが4コアしかない。8コアのOrochiでは、2個のCPUコアが完全に1モジュールに融合していることがダイからもわかる。

 Bulldozerアーキテクチャでは、2個のCPUコアを融合させたクラスタを「Bulldozer Module」と呼んでいる。2スレッドを並列に実行できるモジュールがBulldozerの基本単位だ。Bulldozerのクラスタードアーキテクチャは、1つのモジュールで2スレッドを同時に実行できる。しかし、1つのCPUコアの中で2スレッドを実行する、IntelのHyper-Threadingと異なる。

 IntelのHyper-Threadingでは、CPU全体のリソースを命令単位で2つのスレッドでシェアする。それに対して、AMDではCPUのリソースのうち整数演算パイプは2つのスレッドがそれぞれ専用コアを持つ。しかし、命令デコーダなどのフロントエンドや、浮動小数点演算(FP)ユニットなどは2つのスレッドで共有する。CPUの中でよく使われる部分は2スレッドそれぞれに分離、共有にした方が効率がいい部分はシングルにしたのがBulldozerのクラスタードアーキテクチャだ。それによって、2倍にまでリソースを増やさなくても、2コアに近いパフォーマンスを達成する。

 Bulldozerでは、整数演算は、スレッド間の競合がないため、スループットが高くレイテンシも一定となる。一方、浮動小数点(FP)演算は、通常の用途ではアイドルが多く、レイテンシがクリティカルではないため、共有リソースにしたという。複雑なフロントエンドは2重化せずに、命令デコード帯域を広げることで、2スレッド分の命令のフェッチ&デコードを可能にした。

BulldozerとLlanoのダイ比較
PDF版はこちら
Bulldozerのアーキテクチャ
PDF版はこちら
マルチスレッディングアーキテクチャの比較
PDF版はこちら

●大きなフロントエンドブロック

 2スレッド分の命令ストリームを円滑にフェッチ&デコードするため、Bulldozerのフロントエンドは、従来のK8/K10と比べると著しく強化されている。予測パイプラインは、命令フェッチパイプから独立して動作する。予測機構のガイドによって、命令プリフェッチ機構が予測される命令を先読みする。L1命令キャッシュはK10と同じく64KB、BTB(Branch Target Buffer)のキャパシティはより大きく取られている。

 Bulldozerでは、同じ32nmプロセスのLlano(ラノ)のK10コアと比べてフロントエンドが大型化しているが、その一因は、分岐予測回りの強化にあると推測される。ちなみに、Bobcatも分岐予測の強化によりフロントエンドが大型化している。分岐予測精度を上げることで、ムダな実行を防ぎ、パフォーマンスを上げつつ消費電力を抑えるためだ。電力効率を上げるという目標は、Bobcatのような低電力CPUでも、BulldozerのようなパフォーマンスCPUでも、今や共通している。

Bulldozer ModuleとLlano Unitの比較
PDF版はこちら
Zacate/OntarioのダイとCPUコア
PDF版はこちら

 L1命令キャッシュから、命令フェッチキューへのフェッチ帯域は32-byte幅。命令デコーダは、従来のK10の最大3 x86命令から最大4 x86命令のデコードへと拡張されている。命令デコーダは、IntelのMacro-Fusionと同じように、比較命令と条件分岐命令を融合させることで、命令数を減らす「Branch Fusion」機能を備える。そのため、デコーダの命令フェッチ数は、最大5個のx86命令換算になるはずだ。

 Bulldozerのフロントエンドは、サイクル単位で2つのスレッドをスイッチする。スイッチ型のマルチスレッディングとなっている。そのため、実際には1スレッド当たり平均で2 x86命令/スレッド/クロックの帯域となる。これで、各サイクル4命令発行の整数コア2個に命令スロットを充足できるのは、実行ユニットへの発行時には命令が分解されるからだ。

 x86はCISC(Complex Instruction Set Computer)命令であるため、演算とメモリアクセスの2オペーションが1命令に含まれる場合が多い。実行パイプラインへの発行時に、演算とメモリアクセスの2つの内部命令uOPsに分解することで、4パイプを充填できる。推定される命令のフェッチからディスパッチまでの流れは、下の図の通りだ。

Bulldozerアーキテクチャの実行パイプライン
PDF版はこちら

●物理レジスタファイルでデータ移動を抑える整数ユニット

 Bulldozer Moduleの2個の整数コアは、それぞれ整数実行(Integer Execution)ブロックと、ロード/ストアブロックに分離されている。整数実行ブロックを見ると、実際の実行ユニットは比較的小さく、多くは命令制御やレジスタで構成されていることがわかる。

 整数コアは、整数命令を実行するALUは2個、ロード/ストアのアドレス生成を行なうAGUも2個。合計で4パイプの構成となっている。演算ユニットのうちコストの高い乗算ユニットと除算ユニットだけはそれぞれのALUに1個だけの構成となっている。AGUはロードとストアの両方に対応する。

 整数ユニットでのK10コアとBulldozer Moduleの大きな違いは、レジスタが「物理レジスタファイル(Physical Register Files:PRF)」をリネームする方式に変わったこと。従来のAMDアーキテクチャでは、各命令が参照する64-bitのデータは、パイプラインのリザベーションステージョンの中で、命令に付属していた。しかし、Bulldozerでは、データは全て物理レジスタ(PRF)に納められ、タグである「Physical Register Numbers (PRN)」だけが付属する。実行時以外は、扱うデータが64-bitのデータから8-bitのPRNとなったため、整数コア内部でのデータ移動が減り、より消費電力を削減できるようになったという。ダイエリア上では、物理レジスタをアーキテクチャ上のレジスタにマップするレジスタリネームやPRNを格納するペイロードストレージなどが大きな割合を占めている。

 命令のディスパッチ帯域は4命令/サイクルで、これは2個のALUと2個のAGUに発行される。命令スケジューラのエントリは40命令で、命令をインオーダに並べ替えるリタイヤキューは最大128エントリの命令を制御できる。物理レジスタは96エントリだ。

 L1データキャッシュはK10の64KBから各コア16KBへと少なくなった。しかし、16論理バンク構成のマイクロバンキングによって、バンクコンフリクトの率を以前と同じに保つという。L1データからは128-bitの2ロードと1ストアをサポートしている。しかし、2ポートのロードが同じデータだった場合は、片方のポートが両方のポートに供給することで、無駄なデータ移動とバンクコンフリクトを割けるという。

●大きく3ブロックに分かれた浮動小数点(FP)ユニット

 Bulldozerの浮動小数点(FP)ユニットは、従来のK10のFPユニットの構成を拡張する形となっているという。K10は128-bitの乗算ユニットと加算ユニットの2ユニットと、他の処理を担当するユニットを備えていた。Bulldozerでは、128-bit SIMD(Single Instruction, Multiple Data)の積和算ユニットが2ユニット分と、その他に2命令を処理できるユニット群を備えている。

 Bulldozerでは、FPユニットは2スレッドで共有されている。実行部はSMT(Simultaneous Multithreading)で、2つのスレッドの命令を各サイクルに混在して走らせることができる。この部分だけは、IntelのHyper-Threadingと似たようなスレッド制御となっている。

 FPブロックの中央上半分を占めているのが、FPユニットのコントロールブロックだ。FPスケジューラは、最大4個の命令(uOPs)をピックして実行ユニットに発行できる。各命令最大3オペランドが可能だ。最大60命令までをオンザフライで制御できる。

 実行ユニットは、データパスによって、大きく3つのブロックに分かれている。「ローワーデータパスハンドルズ(Lower Datapath Handles)」と「アッパーデータパスハンドルズ(Upper Datapath Handles)」、それに「ミドルデータパスハンドルズ(Middle Datapath Handles)」だ。ローワーとアッパーが積和算ユニットで、ミドルがシャッフルなどのレジスタ操作やロードのユニットとなっている。

 なぜ3つに分かれているかというと、それはレジスタの分割のためだ。K10では、本来64-bitの演算パプラインを備えていたところに、追加で64-bitパプラインを加えた。ダイ上では、付け足しブロックが明瞭にわかる。それに対して、Bulldozerは128-bit SIMDのためのパイプラインが初めから設計されている。ただし、演算ユニットとレジスタは半分の64-bit SIMDに分割されている。

BulldozerのFPユニットのダイ拡大
PDF版はこちら

●2つに分離されたFPレジスタとFP演算ユニット

 BulldozerのFPレジスタは合計160エントリと極めて大きい。レジスタのデータ部は最大で128-bitのXMMレジスタ(SSE)、またはXMMレジスタを2個分使うと見られる256-bitのYMMレジスタ(AVX)を格納できる。Intelの新命令AVX(Advanced Vector Extensions)をサポートしたためだ。ただし、FPレジスタは、X87/MMXレジスタも兼用している。図中では、ユニットの下部にある2個のオレンジ色のブロックが、2つに分割されたFPレジスタだ。

ベクタ命令の拡張
PDF版はこちら

 左側のオレンジ色のブロックは「ローワーFPレジスタファイル(Lower FP Register File)」、右側が「ハイヤーFPレジスタファイル(Higher FP Register File)」。ローワーFPレジスタは91-bit幅でXMMレジスタとYMMレジスタの下半分とX87/MMXレジスタを格納する。ハイヤーFPレジスタは73-bit幅で反対にXMM/YMMレジスタの上半分を格納する。例えば、SSEで32-bit単精度浮動小数点(FP)の4-wayのSIMDデータを扱う場合、ローワーFPレジスタに半分の2個の単精度データを、ハイヤーFPレジスタに残りの2個の単精度データを格納する。X87/MMXの場合はローワーFPレジスタにだけ格納される。

 両レジスタファイルは、それぞれ演算ユニットに対して、6リード/2ライトのポートを備えている。例えば、ローワーFPレジスタに対しては、ローワーデータパスハンドルズの2個の積和算ユニットが、それぞれ3オペランドを読み出し、1ディスティネーションを書き込むことができる。AMDの図には、ローワーデータパスハンドルズの中に1個の積和算ユニットしか描かれていないが、レジスタポート数から2個の積和算ユニットが配置されていることは歴然だ。同じことが、アッパー側でも行なわれる。

 積和算ユニット自体はSIMDなら1個の倍精度演算または2個の単精度演算を処理できる。SSEやAVXの処理では、アッパーとローワーそれぞれの対称演算ユニットが同一命令を実行することになる。AMDがこうした設計を取った理由は、レジスタと演算ユニットの間の配線を容易にするためだと推測される。

 しかし、レジスタが2つに分割されているため、レジスタ内のデータを入れ替えるようなレジスタの全ビットを使う命令では2つのレジスタファイルに同時にアクセスする必要が出てくる。

 そのため、Bulldozerでは分割されたレジスタの間にミドルデータパスハンドルが配置された。このユニットは、シャッフル/パック/パーミュートといった、レジスタ全体を扱う命令を全て処理する。また、レジスタ全体にデータをロードするロード命令もここでハンドルする。

 左右のレジスタファイルから中央のミドルハンドルに対しては、それぞれ7リードと5ライトのポートがある。ただし、レジスタファイルは合計で10リードと6ライトで、左右へのリード/ライトでポートのうち3リードと1ライトが共有されている。そのため、左右の演算ユニットがフル回転するなら、内側へのポートは制約される。レジスタのバンクは10バンク構成となっている。

BulldozerのFPユニット
PDF版はこちら

●トランジスタ数でもK10コアの2個分程度

 Bulldozer Module全体のトランジスタ数は213M(2億1,300万)。2MBのL2キャッシュは6T SRAMなので単純計算でも2MBで100M(1億)トランジスタを超える。実際には各キャッシュラインにヘッダビットがあり、また冗長回路が付属し、さらにタグRAMもあるので、合計すれば120M(1億2,000万)以上になると推定される。

 ちなみに、LlanoのCPUコアの場合はCPUコア+1MB L2キャッシュ+パワーゲーティングリングで110M(1億1,000万)トランジスタ。その中でCPUコアの部分は約3分の1の35M(3,500万)トランジスタだった。比率からすると、Bulldozerコアのトランジスタ数はK10コアの2個分に近いと推定される。ダイエリアも、ほぼK10換算で2個分なので、これもうなづける。

BulldozerとLlanoのダイ比較
PDF版はこちら

●FO4を20%減らして高速化を図るBulldozer

 Bulldozerは従来のK10系CPUコアと比べて、同じプロセス技術で同じ電力枠の中で、よりも高周波数にできるという。それは、「FO4(Fanout-Of-4)」の数を従来アーキテクチャと比べて20%も減らしたからだ。CPUの動作周波数は、パイプラインステージのディレイに反比例する。ステージのディレイは通常、インバータ「FO4(Fanout-Of-4)」の遅延に換算して示される。

 FO4の数字が低いことは、それだけパイプラインステージのクリティカルパスのゲート数が少ないことになる。1ステージの遅延がFO4換算でより少ないパイプラインの方が、一定電圧時の動作周波数を高くできる。

 パイプラインの動作を速くするには、パイプラインを構成するトランジスタ自体を高速に動かすか、パイプラインステージのゲート数を減らすといった方法がある。前者のトランジスタを高速にする方法では、電圧を上げたり、高速トランジスタを多用することで消費電力を上げてしまう。パイプラインのゲート数を減らすために、パプラインを細分化する場合も、ステージ間のラッチ回路が増えて、これも消費電力が上がってしまう。電力効率の面で一番いいのは、パイプラインのステージ数を変えずに、ゲート数を減らすこと。しかし、そのためには、回路設計の改良や、パイプラインのシンプル化などが必要になる。

高周波数化の手法
PDF版はこちら

 Bulldozerの場合、電力枠を変えずに、高周波数にできるとしているため、最後のパターンだと考えれる。FO4が20%少ないということは、理論上は動作周波数を最大25%上げることができることを意味している。ちなみに、1年以上前からIntel関係者は、Bulldozerの動作周波数が従来より高くなるだろうと観測していた。高速化は、ライバルにとっては予測済みだったとも言える。