您的理解是正确的,但存在一种可能的陷阱:
文档指出:
OpenCL 实现允许在设备内存中缓存由 host_ptr
指向的缓冲区内容。当在设备上执行内核时,可以使用此缓存的副本。
这意味着内核执行对数据所做的更改可能不会立即反映在
host_ptr
中。实际上,在用作缓冲区时,并没有保证
host_ptr
包含有效数据。
为了拥有有效和最新的数据,您必须强制同步。官方文档对此时刻有点模糊不清,但
缓冲区映射/取消映射绝对可行:
如果创建缓冲区对象时在 mem_flags
中设置了 CL_MEM_USE_HOST_PTR,则在 clEnqueueMapBuffer
命令完成时,host_ptr
中指定的区域将包含最新的位;而由 clEnqueueMapBuffer
返回的指针值将派生自创建缓冲区对象时指定的 host_ptr
。
以下是从
Khronos group 论坛帖子中调整的示例:
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);