CUDAはGPGPUのデファクトスタンダードを目指す
TeslaはNVIDIAが開発したGPGPUプログラミング言語「CUDA」で組まれたプログラムを実行する。CUDAについては後述するが、より詳細な解説はこちらの記事を参照して欲しい。ここで簡単に言い表すならば「C言語をベースに、NVIDIAがベクトル計算用に拡張したプログラミング言語」ということかできる。
続いて、Kirk氏はこのCUDAを使ってGPGPUプログラミングを行った際の視点から、Tesla及びGPGPUコンピューティングのプロセスを解説した。
「データ並列コンピューティングではプログラムを書く際には自分がなにをしたいか…だけでなく、処理するデータの構造についても熟慮する必要があります。」(Kirk氏)
全ての処理をGPUに任せることはできないので、データをどういう単位でGPUに並列処理させるのか、そしてGPUが行った計算結果をCPU側でどうシーケンシャルに処理すべきなのかを十分に検討して設計する必要があるというのだ。
図はこれを概念的に表したものになる。
まず、データを「グリッド」という並列データ処理単位としてまとめ、これをGPUに処理させる。このグリッドは複数のデータスレッドからなり、これをGPUが並列計算して処理していく。CPUプログラム(ホストCPU)側は、こうしたグリッド単位の処理をシーケンシャルに取りまとめていく。
グリッドは1~512個のスレッドブロックからなり、これはCUDAプログラマが1~512個の範囲で定義することができる。このスレッドブロックは「CTA:Cooperative Thread Array」(協調型スレッド配列) と呼ばれる。
CTAの配列構成は1次元、2次元、3次元として設定が可能だ。プログラムはCTA単位に実行され、CTAにはスレッドIDが設定されて、これをプログラム側から参照し、処理の同期を取ったりすることも出来る。
このソフトウェア的な視点をハードウェア的な視点に対応させてみていくと、理解が深まるかもしれない。
CTAはSMで実行される。SM内の局所的なデータ同期等はShared Memoryを活用することでCTA単位に行える。もちろんワークメモリ(グローバルメモリ、ビデオメモリ)へのアクセスも許可されているが、この場合は膨大なレイテンシが発生してしまい、このレイテンシを隠蔽するために処理対象のCTAの切り替えなどが行われる。
データ的な視点で見ていくと、1グリッドは複数のCTAからなり、CTAは複数のデータ・スレッドからなる。
各データがそれぞれどのようなメモリリソースに割り当てられているかということを見ていくことにしよう。
まず、各データスレッドを処理する上で必要なローカル変数的なものはSM内部のレジスタファイルに対応する。そしてCTA単位のデータはShared Memoryに格納される。固まりとしては一番大きなグリッド単位のデータはワークメモリ(グローバルメモリ、ビデオメモリ)に格納されている。
「重要なのは、GPGPUプログラムは、動作ターゲットとなるハードウェアが進化した場合にはパフォーマンスが向上できること、GPGPUプログラム側は動作対象GPUのコア数やSM個数を気にせずにプログラム設計ができることです」(Kirk氏)
ここ最近までGPGPUは、今あるGPUを無理矢理汎用目的に活用していくだけの、将来性に不安の残る一発ネタ的な流れだった。しかし、昨年のCUDA発表以降、NVIDIAは、NVIDIA製GPUの将来の姿を気にせずとも、将来に渡って今開発したGPGPUプログラムがちゃんと動作する流れを作り出そうとしている。
そのGPGPUプラットフォームが「CUDA」であり、その動作環境のスペシャルハードウェアが「Tesla」ということになのだ。CUDAを中核として、GPGPUを取り巻く環境を充実させていき、NVIDIAはGPGPUのスタンダードを確立していこうとしているのだ。