1

でopenclオブジェクトstd::vectorのホストポインタとして(またはより正確にはそのストレージ)を使用してみたいという状況があります。サイズが変更されたためにメモリが再割り当てされた場合、これには明らかに問題があります。私への変更は、が使用されていないプログラムのフェーズ中に行われるため、バッファのホストポインタがの最初の要素へのポインタと同一であるかどうかを確認し、そうでない場合はバッファを再作成するという考えです。ケース。私の問題は、が使用されていない場合、ホストポインタがすでに割り当て解除されているを使用することが合法であるかどうかを確認できないことです。bufferCL_MEM_USE_HOST_PTRvectorvectorbuffervectorbufferbuffer

もちろん、使用されているフェーズの最後にバッファーを破棄することもできますが、ベクターの内容や長さが変更されているかどうかは事前にわかりません。変更されていない場合は、古いバッファーを保持したいと思います。デバイスにキャッシュされたままにすることができるafaikなので、pci-eバスを介して転送する必要のあるデータの量を減らすことができます。

私の質問は:オブジェクトが存在するだけでカーネルで使用されていない場合、ホストポインタがすでにホストポインタが削除されているopenclbufferを持つことは許可されていますか?CL_MEM_USE_HOST_PTRbuffer

私が現在nvidiasopencl実装に対して開発している記録として、GPUとしてTesla 2070を使用すると、ソフトウェアは近い将来amd gpus / cpusに移植される可能性があります(後者が使用する主な理由CL_MEM_USE_HOST_PTRです)。したがって、答えが実装固有である場合、それらが主要なターゲットですが、後で他に何が実行されるかわからないため、一般的な答えに本当に興味があります。

4

2 に答える 2

1

OpenCL実装の下のバッファーを変更しようとしなかった方が安全だと思います。あなたが示唆したように、これはおそらく問題をもたらすでしょう。例えば:

vector<int> v(25);
cl_mem buf = clCreateBuffer(.v.data(),.CL_MEM_USE_HOST_PTR,...);
v.resize(1000); //Or some other way of changing the size of the stack
clReleaseMemObject(buf);

メモリが解放されると、データを元のバッファ(割り当てが解除された)に同期しようとし、セグメンテーション違反またはその他の厄介なメモリの問題が発生する可能性があります。

このスレッドに関するいくつかの議論によると、そのメモリの制御をOpenCLプラットフォームに譲渡したというフラグを使用してclCreateBufferを呼び出すとすぐに、CL_MEM_USE_HOST_PTRそのメモリを解放するための呼び出しでのみそのメモリを再利用できると想定する必要があります。 。

特定の実装ではそうではない可能性がありますが、全体としてはデータを公開することをお勧めします。そうすれば、基盤となるシステムが将来変更されても、この動作に関連するバグは発生しません。

オプションで、基になるデータ構造のサイズ変更時にデバイス上のデータを解放して再割り当てできるように、ベクトルクラスを拡張することもできます。ただし、これがどれほど難しいか、またはプログラムの他の部分にどの程度影響するかはわかりません。

于 2012-10-09T17:20:42.813 に答える
0

あなたの質問に対する答えは、バッファを作成するために使用されたフラグによって異なります。CL_MEM_ALLOC_HOST_PTRまたはCL_MEM_COPY_HOST_PTRを指定してclCreateBufferを呼び出す場合、OpenCL実装には、指定したホストの場所のコンテンツのコピーが既にあります(CL_MEM_ALLOC_HOST_PTRの場合、GPU実装の場合はそうする必要があります)。これで、そのホストポインターを使用して自由に実行でき、OpenCLの実装は関係ありません。

一方、CL_MEM_USE_HOST_PTRを使用する場合(これはGPUデバイスであるため、使用しないか、使用できるとは思わない)、おそらくカーネルは実行時にクラッシュするか、ジャンク結果を提供します(その内容に基づいて)現在の場所)。

お役に立てれば!

于 2012-10-09T16:13:45.630 に答える