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

NVIDIAが目指す究極のプロセッサへと進む「Fermi」アーキテクチャ



●グラフィックスにも優れた並列プロセッサへと進化

 NVIDIAは、次世代GPUアーキテクチャ「Fermi (フェルミ)」で、汎用コンピューティングへとさらに一歩踏み出す。

 「以前のG80アーキテクチャは、コンピューティングにも優れたグラフィックスプロセッサだった。しかし、Fermiはグラフィックスにも優れた並列コンピューティングプロセッサだ。設計思想はFermiで変わった」とNVIDIAのTony Tamasi(トニー・タマシ)氏(Senior Vice President, Content and Technology, NVIDIA)は語る。

 NVIDIAにしてみると、あれだけGPUコンピューティングに最適化したG80アーキテクチャでさえ、まだグラフィックスを引きずっており、Fermiでようやくそこから脱したというイメージなのだ。その意味では、Fermiこそ、NVIDIAが目指していたGPUコンピューティングプロセッサの完成図に近い。

 実際にNVIDIAのプロセッサアーキテクチャの変遷を見ると、Tamasi氏の言葉の意味がよくわかる。下のチャートの一番上は、NVIDIAにとって最後のグラフィックスに最適化されたプロセッサだったGeForce 6000(NV40)系のピクセルシェーダプロセッサの構成だ。その下が、GeForce 8000(G80)とGeForce GTX 200(GT200)、一番下がFermiとなっている。上から下へと、NVIDIAがGPUを改革した流れがわかる。

NVIDIA GPUにおけるクラスタの進化

 純然たるGPUだったNV40では、1個のクラスタ「クアッドプロセッサ」に4個のプロセッサがあり、それが4スレッド=4個のピクセルを処理していた。GPU全体ではクアッドプロセッサが4個あり、合計で16プロセッサ構成となっていた。

 各プロセッサの中はSIMD(Single Instruction, Multiple Data)構成の4個の単精度浮動小数点積和算(MAD)ユニットと、1個の特殊演算ユニットSFU(Special Function Unit)が備えられていた。また、テクスチャプロセッサも各プロセッサの中に納められていた。トリッキーだったのは、テクスチャプロセッサを2個目のシェーダプロセッサ群(4wayの積和算+SFU)としても使うことができるようになっていたことだった。

G70のピクセルシェーダ

●異なるスレッドを並列実行するG80アーキテクチャ

 G80ではプロセッサの構造が大きく変えられた。クラスタ全体が「Texture/Processor Cluster (TPC)」として再構成された。1個のTPCの中には、さらに演算プロセッサのクラスタである「Streaming Multiprocessor(SM)」が2個格納されている。命令スケジューラとユニットは各SM毎にあり、SM単位で命令実行は管理される。

 G80の各SMは8個の単精度浮動小数点積和算ユニット(MAD)と2個のSFUユニットを備えている。NVIDIAはG80でもトリッキーな技を使っており、2個のSFUがそれぞれ4wayの乗算ユニットとして機能する。この構造のために、G80のSMはピークで24個の浮動小数点オペレーション(8個の積和算+8個の乗算)を並列実行できる。

G80のStreaming Multiprocessor

 G80がNV40までと大きく異なるのは、複数の演算ユニットを持つ1プロセッサが1スレッドを実行するのではなく、各演算ユニットがそれぞれ異なるスレッドを実行することだ。図をパっと見てわかるように、NV40とG80では、1個のクラスタの中で並列実行できるスレッドの数が大きく異なっている。

 NV40では4個のスレッドそれぞれの命令ストリームの中から、データと命令の並列性を抽出しなければならなかった。これは、1個のピクセルのRGBAの4データ要素に対する演算を並列に行なうケースが多いピクセルプロセッシングでは有利だった。しかし、汎用コンピューティングでは、必ずしもこうしたデータ並列性が存在するとは限らない。演算間に依存性がある場合は、最悪の場合、1命令/スレッドしか実行できず、4個の積和算ユニットのうち3個が遊んでしまう。ATI GPUはこの問題を解決するため、プロセッサをVLIW型へと進化させて、1スレッドの中の異なる命令を並列実行できるようにした。

シェーダプログラムの変化とGPUの対応の違い

 それに対して、G80ではそれぞれの演算ユニットが異なるスレッドを並列実行する。そのため、スレッド内での並列性は一切考慮する必要がない。より汎用コンピューティングに向いている。1つのスレッドの中でのデータ並列性を、スレッドの並列性に置き換えたのが、NV40からG80への革新だった。

●グラフィックスの影をひきずるG80アーキテクチャ

 スレッド並列と言ってもG80のスレッドは、CPUのスレッドのように、それぞれのスレッドが異なる命令ストリームを実行するのではない。同じ命令を実行するスレッドがグループ化されており、並列化された演算ユニットグループが同じ命令を異なるスレッドに対して実行する。つまり、8個のMADは同じ命令を8スレッドに対して実行し、2個のSFUは同じ命令を2スレッドまたは8スレッド(乗算の場合)に対して実行する。

 各演算ユニットが同じ命令を実行するという点ではSIMD/ベクタだが、NVIDIAでは区別しており、「SIMT(Single Instruction, Multiple Thread)」実行と呼んでいる。このあたりが用語の混乱の原因となっているが、ベクタプロセッサを発展させている点はATI GPUやLarrabeeと変わらない。

 G80では、テクスチャユニット以外に、通常のデータロード/ストアを担当するロード/ストアユニットが設けられた。テクスチャユニットとロード/ストアユニットは、物理的には2個のSMから共有される形になっている(論理的には各SMから占有しているように見えるという)。

 G80の構造は、伝統的なGPUからの大きな革新だったが、まだグラフィックスアーキテクチャを引きずっている面もある。例えば、G80のプロセッサクラスタをよく見ると、NV40の再構成的な部分も見えてくる。演算ユニットの構成だけを見ると、NV40の2つのプロセッサを解体して、演算ユニット部分を1個のSMへと編成したのがG80だ。4個のMADと1個のSFUを持つプロセッサを2個合体させて、8個のMADと2個のSFUを持つSMへと編成したと考えることもできる。グラフィックスのワークロードを考えると、G80ではプロセッサ数の比率を大きく変えることができなかったと推測される。G80では、このあたりに、まだNVIDIAの慎重さが見える。

 GT200では、G80からさらにクラスタ構造を発展させた。各TPCは、それぞれ3個のSMを備えている。また、各SMの中に倍精度浮動小数点積和算を実行する専用ユニットを設けた。大きな違いは、演算とロード/ストアの比率が変わり、より演算インテンシブになったことだ。とはいえ、大枠の構造はG80の発展系だった。

●プロセッサクラスタが大きく変化したFermi

 Fermiではこの構造が再度大きく改革される。Fermiでは、G80/GT200世代のようなTPCとSMの2段のクラスタ構造は、少なくともGPUコンピューティングサイドではなくなったと見られる。複雑性を廃して、よりフラットな構造のクラスタへと再編成された。

FermiのStreaming Multiprocessor

 FermiのSMには、16個の単精度浮動小数点積和算ユニット(MAD)が2グループ納められている。特殊演算を実行するSFUも4個納められているが、G80のSFUのように各SFUが4個の乗算を行なうといったトリッキーな構造にはなっていない。あくまでも、超越関数などの専用ユニットとなっている。ロード/ストアユニットもSMの中に格納された。テクスチャユニットも同様にSMの中だと考えられる。

 こうして並べると、NVIDIA GPUではプロセッサクラスタの粒度が次第に大きくなり、またフラットになっていることがよくわかる。NV40とG80では、クラスタの中の演算ユニットの構成自体は大きく変わらなかった。GT200では演算ユニット構成は増やされたが、複雑性は増した。それに対して、Fermiでは、クラスタ内の演算ユニットが増やされただけでなく、よりフラットになった。つまり、より多くのスレッドを、より少ない制約で実行できるようになった。

●効率的だが制約も多いG80系の命令発行

 この違いは、G80/GT200とFermiの命令発行の仕組みを見るとますます鮮明になる。

 G80では1個のSMに1個の命令ユニットがあった。G80以降のNVIDIAアーキテクチャでは、スレッドは「Warp (ワープ)」単位で制御されている。Warpの単位は32スレッド(アーキテクチャ上は16スレッドもサポート可能だとされている)で、Warpの中のスレッドは同じ命令を実行する。つまり、NVIDIA GPUは、32スレッドに対して同じ命令を実行するアーキテクチャを取っており、Warpがそのための単位だ。例えば、グラフィックスなら32ピクセルに対する処理を1個のWarpとしている。

 言い換えれば、Warpの32スレッドは、ベクタプロセッサとしてのNVIDIA GPUの論理ベクタサイズだ。しかし、G80/GT200のSMに搭載されている単精度浮動小数点積和算ユニット「Streaming Processor(SP)」の数は8個。つまり、物理的なベクタサイズは8スレッド並列だ。そのため、各SPは4サイクルに渡って同じ命令を異なるスレッドに対して実行する。マルチサイクルで論理ベクタを実行する構造は、ATI GPUと同じだ。

G80でのWarpスケジューリングの仕組み

 G80のSMでは、1個の命令ユニットが2サイクル毎に1Warpの1命令を発行する。それに対して、メインの演算ユニットであるStreaming Processor(SP)は、4サイクルスループットで1Warpの1命令を実行する。つまり、実行に必要なサイクルの方が、命令発行に必要なサイクルの2倍だ。そのため、論理的にはG80のSMの命令ユニットは、ピークで2つの演算パイプに命令を発行し続けることができる。NVIDIAは、G80の命令ユニットが2命令発行だと説明していたが、その正体はこれだ。

 G80では積和算パイプであるStreaming Processor(SP)は、常に4サイクルのスループットで1つのWarpの1命令を実行できる。しかし、もう1つの演算パイプであるSFUはそうは行かない。SFUは、RCP/RSQ/LG2/EX2/SIN/COSといった三角関数や平方根などの複雑な演算を行なうユニットだ。こうした演算を行なう場合は、各SFUがそれぞれ1サイクルに1スレッドのスループットとなる。そのため、2個のSFUで16サイクルで1Warpの1命令を実行する。その間、SFUに対する新規の命令発行はできない。

 また、G80/GT200系の場合は、SFUを単精度浮動小数点の乗算ユニット兼MOVユニットとして使うこともできた。その場合は1個のSFUが4スレッドを並列に実行できる。つまり、2個のSFUで8スレッドを実行できるため、4サイクルのスループットで1warpの1命令を実行できる。

G80の2命令発行の仕組み

 この他、SMの外にロード/ストアユニットがある。こちらの並列度は明らかになっていないが、G80の設計思想がNV40からのユニット構成をなるべく引き継ぐことにあると考えると8並列だと推測される。

 GT200の場合は、これにさらに1個の倍精度浮動小数点演算ユニットが加わる。倍精度ユニット自体は1サイクルスループットで命令実行が可能だが、1ユニットしかないため、1warpの1命令の実行に32サイクルのスループットが必要となる。32サイクルの間、倍精度ユニットは占有される。

 こうした構造から、G80/GT200系では演算種類のミックスによっては、命令実行の効率がかなり落ちるケースがあることがわかる。実際には、このほかにも、共有メモリのバンクコンフリクトやレジスタアクセスなど、さまざまな部分に制約があった。汎用コンピューティングに向けて最適化が始まったものの、まだ制約が大きかったのがG80/GT200系アーキテクチャだったことがわかる。

GT200の2命令発行の仕組み

●よりフラットになり命令発行の自由度が増したFermi

 ところが、Fermiでは、この複雑性が緩和され、クラスタはフラットな構造になり、より自由度の高い命令発行の仕組みへと変わる。

 FermiのSMには4つのユニットグループがある。演算ユニットであるCUDAコアは16個ずつのグループが2個、SFUは4個のグループ、ロード/ストアユニットは16個のグループ。この4つのグループが、それぞれ並列に異なるWarpの異なる命令を実行できる。CUDAコアは16個/グループであるため、16スレッド並列が物理ベクタ長となる。そのため、32スレッドで構成される1Warpの1命令を、2サイクルで実行できる。ロード/ストアユニットも同様だ。SFUは4スレッド並列なので、8サイクルで1warpを実行する。Fermiでは、SFUが4個の乗算を実行するといったトリッキーな構造はなくなっている。

 命令ユニット自体は2個に増やされており、それぞれの命令ユニットが2サイクル毎に1命令を発行できる。つまり、命令発行は2サイクル毎に2命令の並列が、命令実行は2サイクル毎に3.25命令の並列が可能となっている。数だけを比べると、命令発行が弱いように見えるが、実際には、図のように、かなり効率的に命令発行を行なうことができると推測される。

FermiのWarpスケジューリング