OS XのOpenCL - その14 [OS XのOpenCL]
あまりにちんたらやってるせいで、いつ終わるのかわからないOS XのOpenCL。今日のところはIOSurfaceを使う話。IOSurfaceってなに?という感じでAppleのドキュメントにはIOSurface Frameworkとしてちょっとだけある。プロセス間で共有出来るフレームバッファだと書いてあるんだけど、なんのことだかわからない。どうもGPUのレベルのバッファで、シェアドメモリみたいにして使えるようにしたラッパという雰囲気なんだけど、どういうときにどうやって使うのかこのドキュメントを読んでもわからない。
この節は、効率よく(コピーせずに)OpenCLで使うデータを他のプロセスで共有したいときにIOSurfaceを使う、という話らしい。そういう場合ってどういう場合だろう?やっぱりよくわからん.....
注意:IOSurfaceはMacのプラットフォームに依存した技術ではないが、もし可能ならOpenCLと一緒に使えるような機能をOS Xは提供している。
IOSurfaceからOpenCLイメージを作ったら、OpenCLのC言語を使ってOpenCLの並列化の利点を最大に利用しながらイメージデータを変更することができる。IOSurfaceをプロセス間で渡すためにはIOSurfaceのIDを使う。そうすることで完全に分離されたアプリが同じオブジェクトを共有できる。これによってデバイス間で非常に簡単にIOSurfaceを共有することができる。
既存のIOSurfaceからOpenCLのイメージメモリオブジェクトを作ったら、CPUで走っているメインプログラムからでも、CPUあるいはGPUで走っているOpenCLカーネルからでもIOSurfaceが保持しているデータを変更することができる。
ホストからIOSurfaceを直接変更したり読んだりしたいとき、まずIOSurfaceLock関数を呼ぶ必要がある。そして終わったらIOSurfaceUnlock関数を呼ぶ。でなければ、普通のIOSurfaceとは関係ないイメージであるかのようにOpenCLから使えばいい。
IOSurfaceを操作するためにGCDを使うとき、次のリスト12-1に示すようにIOSurfaceによるOpenCLイメージを作る。 リスト21-1(IOSurfaceによるOpenCLイメージを作る)
CPU(ホスト)がIOSurfaceを変更してそれからOpenCLデバイスと共有するとき、読み書きの前にIOSurfaceをロックして、終わったらカーネルに渡す前にアンロックしなければならない。
OpenCLでIOSurfaceを変更する場合、ロックの必要はない。直接イメージメモリにアクセスすればいい。
自動ベクトライザはスカラプログラムの中の並列に実行できる操作を検出して、最近のCPUが効率的に扱えるようなベクタ操作に変換する。自動ベクトライザを通してコードが実行されることがわかっていたら、ひとつの簡単なスカラプログラムだけを書いて、GPUは同じコードをそのままで実行できる一方で、自動ベクトライザがそのコードをCPUでのパフォーマンスを最大にするようにベクトル化する。
注意:あるGPUではベクトルデータ(ロードやストアの場合)に対してなら、さらに高いパフォーマンスが得られることがある。
{{deafish : よくわからないけど、これはCPUでの効率を上げるためでGPUは関係なさそう。それにLLVMならCPUのベクタユニットを使うようにコンパイルできる。この機能が自動ベクトライザとどう違うのか、実は同じなのかよくわからない。どっちにしろ僕にはあまり関係なさそうなのでスキップする。}}
この節は、効率よく(コピーせずに)OpenCLで使うデータを他のプロセスで共有したいときにIOSurfaceを使う、という話らしい。そういう場合ってどういう場合だろう?やっぱりよくわからん.....
11 OpenCLでIOSurfaceを使う
IOSurfaceとはイメージデータを共有するための抽象化である。コピーを必要としないならIOSurfaceを使えばコピーによる時間を無駄しないので、IOSurfaceはイメージメモリを効率的に使う手段となる。IOSurfaceはAPI、アーキテクチャ、アドレス空間、プロセスによらない。注意:IOSurfaceはMacのプラットフォームに依存した技術ではないが、もし可能ならOpenCLと一緒に使えるような機能をOS Xは提供している。
IOSurfaceからOpenCLイメージを作ったら、OpenCLのC言語を使ってOpenCLの並列化の利点を最大に利用しながらイメージデータを変更することができる。IOSurfaceをプロセス間で渡すためにはIOSurfaceのIDを使う。そうすることで完全に分離されたアプリが同じオブジェクトを共有できる。これによってデバイス間で非常に簡単にIOSurfaceを共有することができる。
既存のIOSurfaceからOpenCLのイメージメモリオブジェクトを作ったら、CPUで走っているメインプログラムからでも、CPUあるいはGPUで走っているOpenCLカーネルからでもIOSurfaceが保持しているデータを変更することができる。
ホストからIOSurfaceを直接変更したり読んだりしたいとき、まずIOSurfaceLock関数を呼ぶ必要がある。そして終わったらIOSurfaceUnlock関数を呼ぶ。でなければ、普通のIOSurfaceとは関係ないイメージであるかのようにOpenCLから使えばいい。
11.1 IOSurfaceの作成と取得
IOSurfaceはコードの中で作ることもできるし、例えばフォトブースのような他の実行中のプロセスに対してIOSurfaceを要求することもできる。IOSurfaceの基礎となるテクスチャ転送メカニズムがGL_UNPACK_CLIENT_STORAGE_APPLE と GL_STORAGE_HINT_CACHED_APPLEを同時に利用する。この転送は、フォーマット変換(あるいはGPUに固有のメモリレイアウトの詳細など)を伴わないシステムメモリからヴィデオッモリへの直接のDMAとして実行される。テクスチャをひとつのIOSurfaceに結びつけているOpenGLコンテクスト(同じプロセスかどうかに関係なく)がいくつあっても、同じシステムメモリとそのデータをコピーしたGPUメモリをそれらすべてが共有する。11.2 IOSurfaceからイメージブジェクトを作成する
IOSurfaceが得られたら、それをOpenCLで使う前に、IOSurfaceを使ってOpenCLイメージメモリオブジェクトを作る必要がある。メモリオブジェクトを作るとき、コピーを作るのではなく、もとになるIOSurfaceと同じメモリを参照するイメージメモリオブジェクトを作ることになる。これによってIOSurfaceを非常に効率的に使うことができる。IOSurfaceを操作するためにGCDを使うとき、次のリスト12-1に示すようにIOSurfaceによるOpenCLイメージを作る。 リスト21-1(IOSurfaceによるOpenCLイメージを作る)
// 2次元イメージ(深さ0か1)あるいは3次元イメージ(深さ > 1)を作る // またはIOSurfaceRefを使ってイメージを作る cl_image gcl_create_image( const cl_image_format *image_format, size_t image_width, size_t image_height, size_t image_depth, IOSurfaceRef io_surface);GCDではなく、OpenCL規格のAPIを使ってIOSurfaceによるOpenCLオブジェクトを作るときはリスト12-2に示すようにclCreateImageFromIOSurface2Dを使う。
cl_image_format image_format; image_format.image_channel_order = CL_RGBA; image_format.image_channel_data_type = CL_UNORM_INT8; cl_mem image = clCreateImageFromIOSurface2D( context, flags, image_format, width, height, surface, &err );
11.3 IOSurfaceをOpenCLデバイスと共有する
OpenCLでIOSurfaceを共有するのは非常に簡単である。鍵はIOSurfaceプロパティをロックすることである。CPU(ホスト)がIOSurfaceを変更してそれからOpenCLデバイスと共有するとき、読み書きの前にIOSurfaceをロックして、終わったらカーネルに渡す前にアンロックしなければならない。
- ホストはIOSurfaceを作成あるいは取得してOpenCLイメージオブジェクトを作成する
- ホストがIOSurfaceに書き込むとき、
IOSurfaceLock(..., write type lock)
関数をホストが呼んで書き込みロックをする。ホストがIOSurfaceを読むだけなら読み込みロックをする - ホストのIOSurfaceに対する読み書きはいつでもできる
- ホストはIOSurfaceUnlock(...)を呼んでIOSurfaceをアンロックする。これはシステムにデータを変更したことを伝えることになる。そのあとIOSurfaceによるOpenCLイメージを使うことができる。IOSurfaceオブジェクトはホストに対して必要となる読み込みロックを内部的に行う
- ホストはOpenCLカーネルにIOSurfaceを渡してキューに投入する
OpenCLでIOSurfaceを変更する場合、ロックの必要はない。直接イメージメモリにアクセスすればいい。
12 自動ベクトライザ
GPUは効率的にスカラデータを処理する。しかしCPUをずっと働かしておくためにはベクトル化したデータが必要である。これはつまり、アプリが実行されるそれぞれのデバイスのためにそれぞれに最適化された異なるカーネルを書くということになるか、あるいはパフォーマンスに苦しむか、ということになる。自動ベクトライザはスカラプログラムの中の並列に実行できる操作を検出して、最近のCPUが効率的に扱えるようなベクタ操作に変換する。自動ベクトライザを通してコードが実行されることがわかっていたら、ひとつの簡単なスカラプログラムだけを書いて、GPUは同じコードをそのままで実行できる一方で、自動ベクトライザがそのコードをCPUでのパフォーマンスを最大にするようにベクトル化する。
注意:あるGPUではベクトルデータ(ロードやストアの場合)に対してなら、さらに高いパフォーマンスが得られることがある。
{{deafish : よくわからないけど、これはCPUでの効率を上げるためでGPUは関係なさそう。それにLLVMならCPUのベクタユニットを使うようにコンパイルできる。この機能が自動ベクトライザとどう違うのか、実は同じなのかよくわからない。どっちにしろ僕にはあまり関係なさそうなのでスキップする。}}
2015-07-28 21:47
nice!(0)
コメント(0)
トラックバック(0)
コメント 0