質問
私は最近のOpenCLでプレーしてきた、と私は唯一のグローバルメモリを使用するシンプルなカーネルを書くことができますよ。今、私は、ローカルメモリの使用を開始したいのですが、私は一度に出力の計算一つの「チャンク」にget_local_size()
とget_local_id()
を使用する方法を見つけ出すように見えることはできません。
たとえば、のは、私が何かの用途ローカルメモリにアップルのOpenCLのHello Worldの例カーネルを変換したいとしましょう。どのようにそれを行うだろうか?ここでは、元のカーネルソースがあります:
__kernel square(
__global float *input,
__global float *output,
const unsigned int count)
{
int i = get_global_id(0);
if (i < count)
output[i] = input[i] * input[i];
}
この例では、簡単に番組がどのようにローカルメモリを使用するようにすることを何かに変換することができない場合は、他の単純な例を行います。
解決
NVIDIAやAMDのSDKのサンプルをチェックアウト、彼らは正しい方向にあなたを指している必要があります。行列の転置は、例えば、ローカルメモリを使用することになります。
あなたの二乗カーネルを使用して、中間バッファにデータをステージングすることができます。追加のパラメータを渡すことを忘れないでください。
__kernel square(
__global float *input,
__global float *output,
__local float *temp,
const unsigned int count)
{
int gtid = get_global_id(0);
int ltid = get_local_id(0);
if (gtid < count)
{
temp[ltid] = input[gtid];
// if the threads were reading data from other threads, then we would
// want a barrier here to ensure the write completes before the read
output[gtid] = temp[ltid] * temp[ltid];
}
}
他のヒント
ローカルメモリのサイズが一定であれば、これを行うための別の可能性があります。リストパラメータのカーネル内のポインタを使用せずに、ローカルバッファはちょうど__localそれを宣言することによって、カーネル内で宣言することができます:
__local float localBuffer[1024];
以下clSetKernelArg呼び出しのためにこのコードを削除します。
でOpenCLのローカルメモリは、ワークグループ内のすべての作業項目間でデータを共有するためのものです。そして、それは通常、(例えば、1つの作業項目は、他の作業項目によって書かれているローカルメモリデータを読みたい)ローカルメモリのデータを使用する前に、バリア呼び出しを行うことが必要です。バリアは、ハードウェアでコストがかかります。覚えておいて、ローカルメモリは、繰り返しデータに使用する必要があります読み取り/書き込みを。バンク競合を極力避けるべきです。
あなたは、ローカルメモリには注意していない場合、、あなたはいくつかの時間グローバルメモリを使用するよりも悪いパフォーマンスで終わる可能性があります。