OpenCL実装の現状
追記: 以下の内容は既に古い。 OpenCLのサポート状況は当時よりだいぶ向上してきたと言える。
OpenCL実装は1.0実装と1.1実装が混在しているのが現状と言える。今のところ、OpenCLは完全なクロスプラットフォームを実現できる状況ではなく、(現状のOpenGLのように)パフォーマンスを追求するならベンダ固有のコードをいくつか追加する必要があるだろう。
試すなら
- MacOS XならAppleの実装一択。(Mac版CUDA toolkitはOpenCLを持っていない)
- nVidiaのCUDA対応GPUを持っているならCUDA toolkit。名前はCUDA toolkitだがOpenCLもサポートしている。機能豊富。CUDA toolkitはGPU上でしか実行できないので、必要に応じてCPU実装もチェックする。
- IntelのCPUを持っているならIntelとATI Stream SDK。
Intelの実装はまだWindows上の32bitアプリケーションにしか対応していない。対応した。 - AMDのCPUまたはATIのグラフィックスを持っているならATI Stream SDK。
ATI Stream SDKではOpenCL ICDへの対応が必須なのに注意する。
IntelやnVidiaの実装はなぜかインストール時に対応プラットフォームかどうかをチェックするので、最もジェネリックに使用できるのはATIの実装だろう。ATIの実装はAMD以外のx86なCPU上でも動作する。
今のところ、OpenCLなアプリケーションを"配布"するための良い方法は無い。(除 MacOS X)
品質
実装の品質に関してはなんとも言えない。
IntelやSNU-SAMSUNGは出たばかりなので殆ど評価していない。foxcやATIの実装はそれなりにバグが有り、あまり推奨できない。しかし、ATIの実装は急速にマシになりつつある。
nVidiaとAppleは悪くないが、動作プラットフォームがかなり限定されている。
実装方針
OpenCL実装の実装方針はいまのところ2つに分けることができる。
(ここでの"フロントエンド"はC言語トランスレータを指す。つまり、CプリプロセサやASTの構築だけでなく、C言語への変換も同様に行なう*1。)
foxcとSNU-SAMSUNGの実装はここに分類される。つまり、OpenCL固有の関数や型を、対応するC言語のVector型に変換し、出力したC言語ソースを通常のC言語コンパイラに通してカーネルの実行イメージを得る。
foxcはctrump( http://ctrump.sourceforge.net/ )ベースのフロントエンドを使用している。
SNU-SAMSUNGはC言語フロントエンドとしてClangを使用している。Clangを使用しているものの、foxc同様コード生成や最適化にはLLVMを使用せず、gccやベンダによるCコンパイラを使用している。
- LLVMよる実装
(ここでの"フロントエンド"はC言語のASTを構築するソフトウェアを指す。例えば、ClangはC言語を自前のASTに変換したあと、LLVMのIRに変換してからLLVMによって最終的なバイナリを出力する。)
Intel、ATIとnVidiaはLLVM中間言語を一旦経由してLLVMで最適化を行い、必要に応じて自前のアセンブラでカーネルバイナリを得ている。
ATIはEDG( http://www.edg.com/ )ベースのフロントエンドを使用している(see 追記)。nVidiaも同様にcudaccではEDGを採用しているように見える。ただし、nVidiaはCUDAのためにOpen64ベースのコンパイラも採用している(gccのフロントエンドとMIPSPro由来のコードジェネレータ)これがGPU側のコード生成に使われているかは定かでない。
Intelは自社のiccコンパイラでEDGを採用しているものの、OpenCLではClangを採用しているのが興味深い。
現在、LLVMのtrunkではPTX(nVidiaのGPU中間言語とそのアセンブラ言語)のサポートが進んでいるので、別の実装が出現する可能性もある。
追記 : 先のLLVM Developer's meetingでATIの実装が紹介され、EDG+LLVMであることが公表された。http://www.llvm.org/devmtg/2010-11/
追記 : nVidiaの実装はnvcompiler.dllを含んでいて、これにはLLVMのPTXバックエンドとclangが含まれているように見える。
実装方針(プロセス)
全ての実装で、OpenCLコンパイラを別のプロセスに分離している。(追記: Intelの実装はClangやバックエンドをDLLに分離しているように見える。)このため、Windows上では、OpenCLカーネルをコンパイルする度にコンソールWindowが登場することになる。。これは少々見栄えが悪い。 追記: 最新のATI Stream SDKでは直ったようだ。
もっとも、ATIを含む多くの実装で、一旦コンパイルしたカーネルを保存し、再使用する仕組みを備えている(OpenCLのAPIがこのような仕様を既に含んでいる)。
また、多くの実装はオフラインコンパイラを別途提供している。これは、OpenCLは"現在計算機に実装されている演算デバイス"を対象にしてデザインされているために、OpenCLのAPIだけでは、"持っていないデバイスのために事前にカーネルをビルドする"ことができないことによる。
実装方針(queue)
OpenCLは、データとカーネルをqueueに入れ、演算デバイスがqueueからそれらを取り出して演算するというスタイルが取られている。
Appleは、(少くともCPU実装では)これらの実装にGrand Central Dispatch(GCD)を使用している。AppleはGCDのデザインをそのまま適用することでOpenCLをデザインしたように思える。
Intelは、これらの実装にThread Building Block(TBB)を使用している。よって、IntelのOpenCLを使用するアプリケーションはTBBのバージョンが限定されることになる。
ATIやnVidiaのGPU実装はGPUのqueueをそのまま使用しているように見える。つまり、ATIの場合はCAL(Compute Abstraction Layer)を使用し、nVidiaの場合もCUDAと同じ低位レイヤを流用している。