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を持っているならIntelATI Stream SDKIntelの実装はまだWindows上の32bitアプリケーションにしか対応していない。対応した。
  • AMDのCPUまたはATIのグラフィックスを持っているならATI Stream SDK

ATI Stream SDKではOpenCL ICDへの対応が必須なのに注意する。
IntelnVidiaの実装はなぜかインストール時に対応プラットフォームかどうかをチェックするので、最もジェネリックに使用できるのはATIの実装だろう。ATIの実装はAMD以外のx86なCPU上でも動作する。
今のところ、OpenCLなアプリケーションを"配布"するための良い方法は無い。(除 MacOS X)

品質

実装の品質に関してはなんとも言えない。
IntelやSNU-SAMSUNGは出たばかりなので殆ど評価していない。foxcやATIの実装はそれなりにバグが有り、あまり推奨できない。しかし、ATIの実装は急速にマシになりつつある。
nVidiaAppleは悪くないが、動作プラットフォームがかなり限定されている。

実装方針

OpenCL実装の実装方針はいまのところ2つに分けることができる。

(ここでの"フロントエンド"はC言語トランスレータを指す。つまり、CプリプロセサやASTの構築だけでなく、C言語への変換も同様に行なう*1。)
foxcとSNU-SAMSUNGの実装はここに分類される。つまり、OpenCL固有の関数や型を、対応するC言語Vector型に変換し、出力したC言語ソースを通常のC言語コンパイラに通してカーネルの実行イメージを得る。
foxcはctrump( http://ctrump.sourceforge.net/ )ベースのフロントエンドを使用している。
SNU-SAMSUNGC言語フロントエンドとしてClangを使用している。Clangを使用しているものの、foxc同様コード生成や最適化にはLLVMを使用せず、gccやベンダによるCコンパイラを使用している。

(ここでの"フロントエンド"はC言語のASTを構築するソフトウェアを指す。例えば、ClangはC言語を自前のASTに変換したあと、LLVMのIRに変換してからLLVMによって最終的なバイナリを出力する。)
IntelATInVidiaLLVM中間言語を一旦経由して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(nVidiaGPU中間言語とそのアセンブラ言語)のサポートが進んでいるので、別の実装が出現する可能性もある。
追記 : 先の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を含む多くの実装で、一旦コンパイルしたカーネルを保存し、再使用する仕組みを備えている(OpenCLAPIがこのような仕様を既に含んでいる)。
また、多くの実装はオフラインコンパイラを別途提供している。これは、OpenCLは"現在計算機に実装されている演算デバイス"を対象にしてデザインされているために、OpenCLAPIだけでは、"持っていないデバイスのために事前にカーネルをビルドする"ことができないことによる。

実装方針(queue)

OpenCLは、データとカーネルをqueueに入れ、演算デバイスがqueueからそれらを取り出して演算するというスタイルが取られている。
Appleは、(少くともCPU実装では)これらの実装にGrand Central Dispatch(GCD)を使用している。AppleはGCDのデザインをそのまま適用することでOpenCLをデザインしたように思える。
Intelは、これらの実装にThread Building Block(TBB)を使用している。よって、IntelOpenCLを使用するアプリケーションはTBBのバージョンが限定されることになる。
ATInVidiaGPU実装はGPUのqueueをそのまま使用しているように見える。つまり、ATIの場合はCAL(Compute Abstraction Layer)を使用し、nVidiaの場合もCUDAと同じ低位レイヤを流用している。

*1:このような言語フロントエンドには例えばcfrontのようにC++→C変換を行うソフトウェアも含まれる。