■後藤弘茂のWeekly海外ニュース■
NVIDIAは、次世代GPUアーキテクチャ「Fermi(フェルミ)」をベースとした次期ハイエンドGPU「GF100」の概要を明らかにした。その正体は、DirectX 11のフィーチャ「テッセレーション(Tessellation)」に最適化した、ジオメトリプロセッシングを強化したGPUだった。GF100の全体像は下の図の通り。
GF100の概要 |
パッと見てすぐにわかる通り、GF100のプロセッサコア全体は、4つのクラスタ「GPC(Graphics Processing Cluster)」に分かれている。GPCは、それぞれがラスタライザなどを備えた、フル機能の「ミニGPU」となっている。いってみれば、“クアッドコア”的な構成となっているのがGF100だ。この“マルチコア化”は、DirectX 11世代GPUのトレンドで、AMD(旧ATI)のDirectX 11世代GPU「Cypress(Radeon HD 5870)」も内部に2つのコアを持っている。
DirectX 11世代GPUの“マルチコア”化 |
両社がGPUのパーティショニング的なアプローチを取った一因は、DirectX 11の機能であるテッセレーションに対応することにある。テッセレータはポリゴンを分割して頂点を増やすため、頂点数が膨大に膨れあがる。そのため、ボトルネックとなる頂点単位のデータをピクセル単位に変換する固定機能ユニット「ラスタライザ」を強化する必要がある。そのための近道が、GPUをパーティショニングすることだった。
GF100の場合は、従来はGPU全体で1個だったラスタライザを、合計で4個に増やした。それに合わせて、GPUを4個のGPCに分割、それぞれが画面上の別なタイルのジオメトリ-ピクセルプロセッシングを行なう仕組みを取った。そして、NVIDIAアーキテクチャでプログラムを独立実行できる最小単位である「SM(Streaming Multiprocessor)」毎に1個ずつテッセレータを実装した。これが、グラフィックス面でのGF100アーキテクチャの大きな特徴だ。
GF100のGPCの構造 |
DirectX 11 APIとGPU実装 |
Fermiのダイ |
●SM(Streaming Multiprocessor)毎にテッセレータを実装
GF100のSM(Streaming Multiprocessor)の内部には、テッセレータを含む主にジオメトリ処理に関連する固定機能群「PolyMorph Engine」が備えられている。正確には、テッセレータを含めたジオメトリに関連する固定ユニット群に、改めてPolyMorph Engineという名前がつけられた。つまり、ジオメトリ関連の固定ユニット群をひとまとめにして格好いい名前をつけただけだ。実際には単なるネーミングの問題で、ハードウェア的に重要なのはテッセレータの追加だ。
NVIDIAは、AMDのようにテッセレータを、SMの外、GPU全体のスレッドを管理するブロックに装備する方法は採らなかった。その代わり、テッセレータを各SMに1個ずつ分散して配置した。
SM(Streaming Multiprocessor)毎にテッセレータを配置するNVIDIAの手法には利点がある。それは、NVIDIAがGPUコンピューティングのために拡張したメモリ階層が、そのままテッセレータのために使えることだ。
前述したように、テッセレータは頂点を生成するため、膨大な量の頂点データが産み出される。そのため、テッセレータは、生成した頂点データを格納するためのバッファが必要になる。GF100アーキテクチャの新しいメモリ階層が、この問題の解決を助ける。
GF100のSMの構造 |
ラスタエンジンとPolyMorth Engineの概要 |
SMの構造2 |
●SMの中のメモリ階層を大きく変革
従来のGPUは、プロセッサ側から読み書きが自由にできるキャッシュを備えていなかった。メインのキャッシュは、上り一方向(メモリ→プロセッサ)のリードオンリーのテクスチャキャッシュだった。下り方向(プロセッサ→メモリ)では、最終段のROP(Rendering Output Pipeline)の内蔵する小さなキャッシュがあるだけで、それもプロセッサ側から自由にアクセスはできなかった。
こうした構造であったため、従来のGPUでは、プロセッサで生成したデータを、プロセッサが再利用することは、グラフィックス処理時には、できなかった。G80(GeForce 8800)以降は、SM(Streaming Multiprocessor)の中に16KBの共有メモリを備えたが、これはGPUコンピューティング時にしか利用できず、それも明示的にデータを格納する必要があった。共有メモリは、プロセッサ側から自由に読み書きできるが、グラフィックスには役立てられなかった。
それに対して、GF100では、プロセッサ側から自由に読み書きができるキャッシュ階層が搭載された。それによって、オンチップで演算結果を再利用する「プロデューサ-コンシューマ局所性(Producer-Consumer Locality)」の活用と、「ローカルワークセットアップデート(Local Working-set Update)」がグラフィックスでも比較的容易に行なえるようになった。また、GPU全体で見ると、G80/GT200系と較べて、レジスタ数はそれほど増えておらず、マルチスレッディング能力(インフライト制御できるWarp数)は逆にGT200より減っている。しかし、メモリ階層は大きく増やされており、これが、Fermiアーキテクチャの大きな特徴となっている。
G80とGT200とGF100のメモリ量の違い |
●キャッシュ階層がデータの柔軟性を高める
具体的には、GF100では各SMの内部に、コンフィギュラブルなローカルメモリとして64KBが搭載された。このメモリは、48KBの共有メモリと16KBのライタブルL1キャッシュまたは16KBの共有メモリと48KBのライタブルL1キャッシュの組み合わせに切り替えることができる。キャッシュ部分は、CPUのキャッシュのように、ハードウェアでキャッシュ制御される。
さらに、GPU全体で共有するライタブルなL2キャッシュが768KB備えられた。CPU的に言えば、コア単位のL1キャッシュと、コア間で共有するL2の2階層のキャッシュを持っている。ちなみに、L2からメモリへのキャッシュはライトバック制御、L1からL2へはアクセスによってライトバックとライトスルーの2パターンの制御のいずれかを取る。NVIDIAによると、キャッシュ制御ができるロード/ストア命令がネイティブ命令であるという。コヒーレンシはAtomicオペレーションで取っている。
このハードウェア制御キャッシュは、一部のGPUコンピューティングアプリケーションや、レイトレーシングなどで効果を発揮する。しかし、DirectXグラフィックスパイプラインでも、実は効果があるという。ジオメトリパイプラインで、各シェーダステージやテッセレータで生成したデータをキャッシュに保持して再プロセッシングができるからだ。
テッセレータでは、データ量が不特定に肥大化する、つまり、出力する頂点データの量が予想しにくい。そのため、フレキシブルなキャッシュが効果を発揮すると考えられる。テッセレータをSMの外に実装してSM間で共有した場合は、テッセレータ側にバッファを設け、さらにテッセレータからSMへと戻すバスも広く用意する必要がある。しかし、GF100の実装の場合は、テッセレータがSMの中にあるため、バッファはSM内のメモリで、バスはSM内の広帯域バスでまかなうことができる。
GF100とGT200のメモリ階層 |
GF100の処理の流れ |
GT200とGF100のキャッシュ容量 |
●SM当たりのプロセッシングパフォーマンスを高める
NVIDIAはGF100において、SMの規模を拡大して、内部の演算コア数を約4倍に増やした。SMのプロセッシング能力を高めたのは、SM単位で実装されているテッセレータとのバランスを取るためとも考えられる。
具体的には、従来のG80/GT200系では、各SMは8個のプロセッサコア「Streaming Processor(SP)」を搭載していた。それに対して、FermiではSM内のプロセッサコアは32個に増えた。SMの中のプロセッサコアは、G80/GT200ではSPと呼ばれていたが、GF100では「CUDA core」と呼ばれている。
GT200のSMの構造 |
GF100のSMの32個のCUDAコアは、実際には16個ずつの2つのグループに分けられている。2グループのCUDAコアで並列実行が可能だ。CUDA coreは倍精度浮動小数点演算に対応しただけでなく、内部データパスが2倍になり、浮動小数点演算パイプと整数演算パイプが分離された。結果として、整数演算性能がG80/GT200より高くなっている。
G80/GT200系では各SMに4個のSpecial Function Unit(SFU)と1個の命令ユニットが搭載されていた。また、GT200からは各SMに1個の倍精度浮動小数点演算ユニットが加えられていた。それに対して、Fermiでは各SMに4個のSFUが搭載されておりSFUとプロセッサコアの比率が変わった。
●テクスチャユニット4個をSMに内蔵SM内のプロセッサコア数は変わったが、論理上のベクタ長であるWARP内のスレッド数は32のまま変わらない。WARPは「SIMT(Single Instruction, Multiple Thread)」実行、つまり同期して同じ命令を実行するスレッドの束で、一般的なベクタマシンのベクタ長にあたる。GF100では最大48のWARPをインフライトで制御できる。命令ユニットはデュアルになり、異なるWARPの命令を、実行ユニットグループのうち2つに、同時に発行することができる。
FermiのWarpのスケジューリング |
SMには、この他グラフィックス専用ユニットとして4個のテクスチャユニットが含まれている。NVIDIAのG80/GT200系アーキテクチャでは、テクスチャユニットは複数のSMで共有する構成となっていた。GF100からは、SMがテクスチャユニットを占有するアーキテクチャとなっている。
各テクスチャユニットは、それぞれ1個ずつのテクスチャアドレス生成ユニットと、テクスチャフィルタリングユニットを備えている。テクスチャユニットは、従来のG80/GT200系アーキテクチャでは、GPUのベースクロックで動作していたが、GF100ではクロックプレーンが分けられ、より高クロックで動作するという。
NVIDIAアーキテクチャの比較 |
NV40以降のGPUプロセッサユニットの比較 |
●GPU全体のバス構造を変革してメモリ階層の拡張をサポート
GPC/SMは双方向クロスバースイッチ(Bi-directional Crossbar Switch)に接続されている。GPUはこれまで、上り方向(メモリ→プロセッサ)のテクスチャ用クロスバースイッチと、下り方法(プロセッサ→メモリ)のROP(Rendering Output Pipeline)用クロスバースイッチの2つの分離されたパスを備えていた。独立した片方向クロスバースイッチ(Uni-directional Crossbar Switch)を2つ組み合わせていた。
しかし、GF100では統合型の双方向クロスバースイッチに組み直された。これは、リード&ライトが可能なキャッシュ階層を備えたことで、リードアフタライトのデータハザードが生じるのを防ぐためだ。上下に分離されたパスでは、値を書き込む前に、古い間違えた値を読み出すといった問題が生じる危険がある。GF100の統合型の双方向クロスバースイッチは、この問題を解決できる。
ただし、厳密には完全に双方向へと統合化されたわけではなく、上りのテクスチャリード専用のパスは片方向のまま残されている。トラフィックが極端に多いテクスチャリードを分離することで、双方向クロスバの負担を軽減することが目的だと推測される。
●ROP回りのバス構造も大きく変更クロスバは6個のメモリコントローラ毎に分割されたバックエンドのパーティションに接続されている。768KBのL2キャッシュも、実際には6個のメモリコントローラに分散されて配置されている。それぞれのコントローラのDRAMアドレスに対してのキャッシュとなっていると見られる。
ピクセルのフレームバッファメモリへの書き出しを制御するROPサブシステムも6パーティションそれぞれに配置されている。ROPは、以前は下り一方向(プロセッサ→メモリ)のパスにつなげられており、上り方向(メモリ→プロセッサ)のL2テクスチャキャッシュとは分離された。しかし、GF100ではROPユニットもL2キャッシュに接続され、双方向バスでプロセッサ側と接続されている。
ROPの中には、依然として非常に小さなキャッシュがあるが、隣接する大容量のL2キャッシュにROPデータがストアされるため、これまでよりキャッシュヒットが高くなるケースがある。ROP自体も拡張されており、ユニット数は各サブシステム毎に8個。GF100全体で48個の構成となっている。
メモリインターフェイスの幅は384-bitで、これはG80世代と同じ。ただし、従来のGDDR3より高速なGDDR5をサポートする。データ転送レートは大幅に上がりメモリ帯域も向上する。
GF100のメモリコントローラは64-bit幅だが、内部の構造は変わっている。GDDR5は、メモリセルアレイからデータを読み出す粒度であるプリフェッチ幅がDDR2やGDDR3より広い。DDR2のPrefetch 4に対してPrefetch 8となっている。
そのため、DRAMコントローラのチャネルの幅を狭めなければ、メモリアクセスの粒度が上がってしまう。メモリアクセス粒度が大きくなると、メモリにアクセスする際の無駄が発生する可能性が高くなる。NVIDIAは、GF100ではこの問題を解決したと説明しており、DRAMコントローラのチャネルの幅は、従来の64-bit幅から32-bit幅に狭まっていると見られる。
DRAM Prefetchのアーキテクチャ |
こうして全体像を概観すると、GF100が従来のGPUとは大きく異なることがよくわかる。NVIDIAは、GPUアーキテクチャの改革を継続している。