ページ

ラベル OpenCL の投稿を表示しています。 すべての投稿を表示
ラベル OpenCL の投稿を表示しています。 すべての投稿を表示

2014年3月14日金曜日

デジタル・マーブリング





本当はSICFというイベントで発表できたら、と考えていたのですが、
あえなく落選してしまい、発表場所もなくなったのでブログに公開します。

最初の構想の元になっていたのは
マーブリングという水の上に絵の具を落としていく技法です。
子供の頃に水の上の絵の具を流して遊んだことがある人は多いと思いますが、
あれです。

動画はトルコの職人さんによるもの。
見入ってしまいます。


で、これをPC上で再現したら面白いんじゃないかと思い、
まず考えたのが、水流を再現するにはどうしたら?
ということでした。

で、調べた結果、どうやら流体力学というものをPC上で
再現できれば、出来そうだということはなんとなくわかったのですが、
正直、数学・物理に疎いので理解できず・・・

幸い、流体シミュレーションを開発・公開されている方が
それなりにいて、今回の制作には以下のライブラリを参考にしました。
ソースコードから理解していくという作戦です。

Thomas Diewald
http://thomasdiewald.com/blog/?p=95


このライブラリはjavaで記述されていて、GPUを使うバージョンも
公開されていたのですが、ダウンロードして動作したのはCPUバージョンのみ。
CPUバージョンだからかパフォーマンスも正直、イマイチ。

今回はopenFrameworksを使うつもりでいたのと、
パフォーマンスを改善することを目的に
まずはライブラリをC++に移植するところから開発をスタート。

とりあえず、単純にjavaの文法をC++にするレベルの移植を終えて、
動かしたところ、パフォーマンスはそれほど変わらず・・・
マシンにインストールされているのはjava6なんですが、
java6、かなり速いです。

次にロジックを見直して不要そうな部分をどんどん省いていったんですが、
これも対して効果なし。

残る作戦はGPUを使った並列処理化しかない、
と思いはOpenCLでロジック部分を実装。
結果はかえって遅くなる始末。
さすがにこれにはヘコみました。

それでも納得できなかったので
いろいろと試した結果、GPUでの並列化でなく、
CPUでの並列化の方が速いことが判明。
やっと満足いくパフォーマンスを得ることができました。
たぶん、内部的にはCPUコアをフル活用しているんだと思っています。

GPUでの並列処理が遅い明確な理由は未だにわかってないのですが、
今回、プログラムでは2次元配列を多用しており、
GPU側のメモリへの転送速度がネックになっているんだと推測しています。

openCL慣れてくれば、かなり応用範囲の広い技術な気がしています。
今回はデータ並列(同じ処理を複数同時に行う)しかしてないんですが、
タスク並列(違う処理を同時に行う)でやれる部分もあったりしますし、
openGLとメモリ領域を共用して描画速度をもっと早めたりもできそうですし。
以前、作成したチューリングパターンなんかにも応用できそうです。

ちなみに今回の開発環境は以下のとおりです。
何かの参考になれば。

【Hardware】
PC : mac book pro(Late 2012 15-inch)
CPU : Intel Core i7 2.3GHz
GPU : NDIVIA GeForce GT650M

【Software】
OS : mac os x 10.8.5
openFrameworks : v0.8
OpenCL : 1.1