変数が CL_MEM_USE_HOST_PTR を使用してカーネルに渡される場合、デバイス内の変数への変更はホスト メモリにも表示されるということですか?
GPU の代わりに CPU をデバイスとして使用しているシナリオにいるため、カーネルに渡されるすべてのものが CL_MEM_USE_HOST_PTR でマークされます。
これが本当なら、ホストにすべてを読み戻す必要がなくなり、非常に便利です。
変数が CL_MEM_USE_HOST_PTR を使用してカーネルに渡される場合、デバイス内の変数への変更はホスト メモリにも表示されるということですか?
GPU の代わりに CPU をデバイスとして使用しているシナリオにいるため、カーネルに渡されるすべてのものが CL_MEM_USE_HOST_PTR でマークされます。
これが本当なら、ホストにすべてを読み戻す必要がなくなり、非常に便利です。
あなたの理解は正しいですが、考えられる落とし穴が 1 つあります。
OpenCL の実装では、 が指すバッファーの内容
host_ptr
をデバイス メモリにキャッシュできます。このキャッシュされたコピーは、カーネルがデバイスで実行されるときに使用できます。
これは、カーネルによって実行されたデータへの変更が、すぐに に反映されない可能性があることを意味しますhost_ptr
。実際、host_ptr
バッファとして使用されている間、有効なデータが含まれているという保証はありません。
有効で最新のデータを保持するには、同期を強制する必要があります。公式ドキュメントは現時点で少し曖昧ですが、バッファのマッピング/マッピング解除は確実に機能します:
バッファ オブジェクトが
CL_MEM_USE_HOST_PTR
set inmem_flags
で作成された場合、host_ptr
指定された in には、コマンドが完了しclCreateBuffer
たときにマップされている領域の最新のビットが含まれていることが保証されます 。clEnqueueMapBuffer
によって返されるポインター値は 、バッファー オブジェクトの作成時に指定されたclEnqueueMapBuffer
から派生します。host_ptr
以下は、Khronos グループ フォーラムの投稿から抜粋した例です。
cl_mem device_output = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, size, original_output, NULL);
// run the kernel
void* pointer = clEnqueueMapBuffer(queue, device_output, CL_TRUE, CL_MAP_READ, size, 0, 0, NULL, NULL, NULL);
// work with 'original_output'
clEnqueueUnmapMemObject(queue, device_output, pointer, 0, NULL, NULL);
clReleaseMemObject(device_output);