1

私は OpenCL でいくつかの開発を始めています。私の最初の目標の 1 つは、大量のデータを含むライブラリを OpenCL に移植することです。

この特定のライブラリは、値が厳密に一定である多数の配列の配列 (メモリ内で約 20MB) のネイティブ C 形式と、ユーザーが抽出できるようにする (場合によってはいくつかの基本的な操作を実行できる) いくつかの関数で構成されます。 ) これらの配列の値。

これらすべての配列を、関数のコードと一緒にライブラリにコンパイルする巨大な C ソース コード ファイル (約 1M 行) にまとめています。

私の質問は次のとおりです。この巨大なファイルを、必要なメモリ修飾子を使用して、データセットと関連する関数を使用する OpenCL カーネルにコンパイルすることは何とか可能ですか? 繰り返しますが、これらの配列は定数であり、実行中に変更されることはありません。

すべてのアドバイスを事前にありがとう!

トム

4

1 に答える 1

2

OpenCL は、まさに探している定数メモリをサポートしています。グローバルメモリと同様に機能しますが、正確な配置は実装によって異なります。また、カーネルの実行中にメモリが変更されないことが保証されているため、コンパイラはさまざまな方法で最適化できます。

このバッファーを作成し、読み取り専用としてマークし、ホストがアクセスできるデータからコピーします。次に、通常どおりカーネルに渡します。

float[] hugeData = { ... };

void run_kernel() {
   // ...
   cl_mem cl_hugeData;
   hugeDataInOpenCL = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(hugeData), hugeData, &error);
   // ...
   clSetKernelArg(kernel, 0, sizeof(cl_hugeData), &cl_hugeData);
   // ...
}

__kernel void mykernel (__constant float * hugeData, ...) {
   // use hugeData however you want
}

おそらく、過度の再作業を避けるために、コンテキストごとに 1 回バッファーを作成し、それを (カーネルの場合と同様に) 再利用することをお勧めします。

また、データが十分に大きいため、一部のデバイスでは使用可能な定数メモリが十分にない可能性があります。その場合は、グローバル メモリを使用して読み取り専用にマークする方法にフォールバックできます。(これは、カーネルの 2 つのバージョンを意味し、いずれかのタイプのパラメーターを持つものです。) 実行時に確認clGetDeviceInfoCL_DEVICE_MAX_CONSTANT_BUFFER_SIZEて決定します。

于 2012-09-21T14:07:39.080 に答える