C++ AMP(C++ Accelerated Massive Parallelism)、知ってますか?
CUDAでもOpenCLでもない、Microsoft主導の異種混在(ヘテロジニアス)計算機での環境です。
このC++ AMP、「Microsoftが」というとDirectXみたいにWindows(Visual Studio)でしか動かないと思ってませんか?
大昔はそうでしたが、現在はLLVM/clangベースのKalmar(旧clamp)を使うことでLinuxでも(たぶんMacでも?)C++ AMPを使うことができます。
使い方はとっても簡単。Kalmarのトップページに従って、
- 予めclangをインストールしておいて
- (Ubuntuなら).debをダウンロードしてdpkgでインストール
-
/opt/kalmar/bin
にパスを通して -
clang++ `clamp-config --install --cxxflags --ldflags` main.cpp
でコンパイル&リンク
で出来ちゃいます。
Windows(Visual Studio)版と違うのは
- 実体はOpenCL CかSPIRへの翻訳機なので、concurrency::accelerator::get_description()メソッドでも何のデバイスが取得出来てるのかさっぱり分かりません(get_allして表示してみましたが、私の環境では全部「OpenCL」と言われて終わりました。なんだそれ?)
- ただそのおかげで、WDDMの制約はないので、倍精度演算が普通に使えます1。
- たまに
No section
とか警告が出たりしますが無視してもよさそうです(実行可能ファイルは出力されていて普通に実行できるので)。
と言ったあたりです。
C++ AMP自体の使い方はベクトルの加算ぐらいなら簡単なので、実際にはコードを読んでみたりしてください(そのうちどっかに書くかも)。
実際の処理時間ですが、適当にN体問題で比較してみた結果、
で、10[%]ぐらいのコストでした。
OpenCLを使う場合はOpenCL Cへの移植があってちょっと面倒ですが、C++ AMPならほぼC++のままで動かすことができる2ので、その移植コストを考えたら10[%]ぐらいなら許容範囲かなと思います。
「C++ AMPなんて流行ってないじゃん」「CUDAで/OpenCLでいいじゃん」って言う方もいるかもしれませんが、
- CUDAのようにベンダーロックがかかっていないので、大多数のプラットフォームで動かすことができる
- OpenCLのようにデバイス側の(カーネル)コードが別管理ではないので、構造が単純になる。例えば、thrustのような汎用的なライブラリを作りやすい(Boltは・・・まぁ全然うまく行ってないので仕方ない)
という両方の長所を兼ね備えているのは今のところC++ AMP以外には存在していません。
銀の弾丸ではないので盲信は避けるべきですが、Linuxでもこれだけお手軽に使えるとなると、これからもう少し本気で使ってみようかなと思いました。
-
Windowsの場合、倍精度演算の完全サポートにはWDDM1.2以上(つまりWindows8以上)が必要です。 ↩
-
実際には、関数宣言にrestrict(amp)が必要で、その関数内ではいくつか制約があります(特に
std::size_t
が使えなかったりするのは地味にめんどい)。 ↩