SSブログ

OS XのOpenCL - その8 [OS XのOpenCL]

OS XでのOpenCLのプログラミングガイドを訳している。できればさっさと終わらせたいんだけどまだある。今日はメモリオブジェクトの扱いのところ。

6  OS XのOpenCLのメモリオブジェクト

OpenCLは普通のプログラムとは違ったやり方でメモリを使う。この章ではOpenCLアプリで使うメモリバッファとイメージを紹介する。

6.1  概要

普通の計算プロセスと同じようにOpenCLデバイスで走るプロセスには
  • データ
    OpenCL命令がアクセスするデータにはcl_imageメモリオブジェクトとメモリバッファがある。イメージオブジェクトは2〜3次元の画像のために使われる。バッファオブジェクトはそれ以外の汎用のデータのために使われる。
  • OpenCLプログラム中のデータを操作する命令
GPUのような多くのデバイスでは、OpenCLメモリは物理的に独立したシリコンの小片に収容されている。それ以外のデバイスではデバイスメモリは物理的に同じチップにある。物理的な場所に関わらずデバイスメモリはデバイスメモリはカーネルコードだけが読み書きでき、ホストメモリはホストだけが読み書き出る。

言い換えれば、ホストとOpenCLのメモリが物理的に近くにあったとしても、ホストメモリはOpenCLメモリとは違っている。カーネルはOpenCLデバイスにあるメモリしかアクセスできない。ホストコンピュータはデバイスメモリを読み書きできるが、それを設定したり結果を読みだしたりできるだけである。計算の間はデバイスはデバイスメモリの内部だけを見て、ホストはその間待つしかできない。

ホストによってデータがカーネルに渡されたとき、データは実行時にはOpenCLデバイスに常駐している。カーネルはホストメモリを読み書きできない。カーネルはデバイス自身の分割されたメモリエリアだけにアクセスできる。

6.2  メモリの可視性

典型的なマルチデバイス環境では、メモリは複数のデバイスに分散している。全てのメモリアクセスできデバイスは存在しない。図-4はOpenCLシステムのメモリ空間を表している。それぞれのメモリ空間はホストとカーネルにとって異なる可視性を持っている。
0519fig04.png
  • プライベートメモリは一つのワークアイテムだけがアクセスできるメモリである
    ホストやほかのワークアイテムはプリベートメモリを読んだり書いたりはできない
  • ローカルメモリはワークアイテムがワークグループ間で共有するメモリである。ローカルメモリはグループ内の一つ以上のワークアイテムがグローバルメモリの特定のかたまりをアクセスするときに役にたつ。一つのワークアイテムがグローバルメモリからローカルメモリにデータをロードするようにOpenCLプログラムを書くことができる。そうするとデータの一部が必要な他のワークアイテムがローカルなコピーにアクセスできるようになる。
    GPUデバイスにとってはグローバルメモリよりもローカルメモリにアクセスする方が速い。ホストはローカルメモリを読み書きすることはできない。
  • グローバルメモリはすべてのワークアイテムが見ることのできるデバイスのメモリの相対的に大きなかたまりである。グローバルメモリにあるとされたバッファはすべてのワークアイテムが読み書きできる。ホストもグローバルメモリは読み書き可能である。
  • コンスタント(定数)メモリはグローバルメモリの特別な一部分で、カーネルが実行している間値が変わらないことがわかっているメモリである。普通は他のタイプのグローバルメモリよりもサイズは限定されているが、デバイスからは速くアクセスできる。コンスタントメモリはホストも読み書きできる。
例えば、OpenCLカーネルはそれを呼び出したホストから分離されたメモリ空間で実行される。カーネルが操作するためのデータにアクセスするには、データはデバイスメモリに移動されなければならない。しかし、異なるデバイスが操作できるようにするのにデータをメモリエリア超えて移すのはそれなりのオーバーヘッドがある。パフォーマンスを最適はするためには、データの転送は最小限にしなければならない。

ホストはカーネルの引数を宣言するとき与えられたバッファ用にメモリ空間を特定する。

6.3  メモリの一貫性

ワークアイテムがグローバルやローカルメモリした変更は同じワークグループ内の他のワークアイテムがすぐに見えるようになるわけではない。そのときシステムの一貫性が教えてくれる。

OpenCLは緩めたメモリ一貫性モデルと呼ばれるものを使っている。それは
  • ワークアイテムはプライベート、ローカル、コンスタント、グローバルなメモリ空間にアクセスできる
  • ワークアイテムはワークグループが実行している間、ローカルメモリを共有する。しかし、定義された同期ポイントを超えたときにしかメモリの一貫性は保証されない
もしワークアイテムが書いたものを他のワークアイテムが読む必要があるとき、OpenCLカーネルコードのメモリが一貫性を持って欲しいところで、バリアビルトイン関数を呼べばよい。
barrier(CLK_LOCAL_MEM_FENCE);
barrier(CLK_GLOBAL_MEM_FENCE);
barrier(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);

他のワークアイテムがキャッチアップするまで、バリアは呼ばれたところでワークアイテムの実行を停止する。バリアに到達したときには一つのワークグループ内のすべてのワークアイテムはメモリを書き終わっている。従ってグループ内のワークアイテムが書いたものは安全に読み出すことができる。

注意:バリアはローカルメモリにもグローバルメモリにも設定できる。しかし一貫性は一つのワークグループ内に限られる。すべてのスレッドが実行を停止するようなグローバルメモリバリアのようなものは存在しない。OpenCLはワークグループ内のメモリ一貫性だけを保証している。

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。