■■OpenCL デバイス

■構成


OpenCL デバイスは 1 つ以上の計算ユニット Computation Unit (CU) から構成されており、CU は 1 つ以上の処理エレメント Processing Element (PE) から構成されている。PEをスレッドとも言う。

大きさの比較
スレッド(PE) ＜ CU ＜ デバイス

スレッド上で実行されるカーネルは、主に以下の 3 種類のメモリにアクセス可能である。




(1)レジスタ(プライベートメモリ)
	・カーネル内で「__private__」指示子を用いて宣言された変数がプライベートメモリとして扱われる。
	・スレッドごとに独立したレジスタとして利用可能。
	・高速で低レイテンシ。
	・デバイス関数内で宣言された通常の変数は基本的にレジスタへ割り当てられる。
	・CPUから直接読み書きすることはできない。
	・GT200ではCU毎に16384本。
(2)共有メモリ(ローカルメモリ)
	・カーネル内で「__local__」指示子を用いて宣言された変数が共有メモリとして扱われる。
	・同一CU内の各スレッドからは同一メモリとして利用可能。
	・高速で低レイテンシ。
	・CPUから直接読み書きすることはできない。
	・カーネル処理が終わると自動的に解放される
	・barrier(CLK_LOCAL_MEM_FENCE)でCU内スレッドが同期できる
	・GT200では各CU毎に16KB。
(3)グローバルメモリ(VRAM)
	・カーネル内で「__global__」指示子を用いて宣言された変数がグローバルメモリとして扱われる。
	・GPU全体で共有されるメモリ。
	・全CU、全スレッドから同一メモリとして利用可能。
	・連続アクセス(バースト転送)では高速で高レイテンシ。
	・ランダムアクセスでは低速で高レイテンシ。
	・CPUからAPIを介して値を読み書きすることができる。
	・CUをまたいでデータを保持することができる。
	・実体は主にGDDR5と言われる部分

ここで用語の整理

VRAM＝ビデオメモリー＝デバイスメモリー＝グローバルメモリー＝GDDR5（アクセス一番遅い）
共有メモリー　＝　1次キャッシュ　＝　ローカルメモリー　（少し早い）
プライベートメモリー＝レジスタ　（一番早い）　

■インデクス空間
カーネルが実行される際，ホストプログラムによって n 次元 (n = 1〜3) の抽象的なインデクス空間が定義される．インデクス空間の各座標には次元を表すための n 組の整数値と，ワークアイテムと呼ばれるカーネルの実行インスタンスが割り当てられている．さらに，ワークアイテムをまとめたものをワークグループと呼び，ワークグループをまとめたインデクス空間全体のことを NDRange と呼ぶ．ワークアイテムに割り当てられている整数値をグローバルID と呼び，ワークグループに割り当てられる整数値をローカル ID と呼ぶ．このようなインデクス空間を用いたプログラミングは，一般的に逐次処理におけるループを使った処理を並列化する際に利用される．OpenCL では予め実行前に n × m の座標を持ち，それぞれの座標に i，j に相当する値が与えられているインデクス空間を用意しておく．これにより OpenCL では，対象の座標を実行時に計算する必要がなく，実行の際にはそれぞれの座標に対応したワークアイテムを非同期に呼び出すことで，並列処理を実現している．




■■OpenCLとOpenGLの違い
（あるブログの説明がわかりやすかったので一部改変してコピペします。）

■一言で
OpenCLとはOpen Computing Language の略称で，GPUなどで計算を行うための開発環境（API群）
OpenGLはOpen Graphics Library の略称で，3DなどをGPUなどのアクセラレータを介して処理するためのライブラリ群

■OpenCLとは
GPUなどで計算を行うための開発環境で
個々のソフトウェアの開発者が毎回すべての機能をゼロから開発するのは困難で無駄が多いため共通のデータ形式などを定めた規約である

■OpenGLとは
3Dグラフィックスのためのライブラリ（複数のプログラム部品を一つのファイルにまとめたもの）であり。ライブラリ自体は単独で実行することはできず、他のプログラムの一部として動作する。


■連携について
OpenCLで処理したデータをGPUのDVIポートを介して出力させるためには、OpenGLと連携させなければいけません。
OpenCLだけでできるようにしてくれたらどれだけ便利なことか。どちらもkhronosが決めている奴なので、互いに干渉しないようにしているのか、はたまた面倒くさいだけなのか、もっと違う理由があるのか。

使い方のイメージとしては，まずOpenGLを優先的に立ち上げます。
この時、Windows環境では使うディスプレイごとにデバイスコンテキストというものがあるので、それを取得します。
ついで、OpenGLでデバイスと描画を関連付けるレンダリングコンテキストを立ち上げます。
んで、ピクセルフォーマット（ウィンドウの詳細設定みたいな）ものを決めて、初期化します。
そしてOpenGLで立ち上げたコンテキストやバッファをOpenCLのそれと関連付けます。
このとき関連付けできなければ、OpenCLとOpenGLそれぞれ単独で扱えても連携はできないことになります。
古いノートパソコンのオンボードだとこのような現象が起こります。
