OpenCL:使用CL_MEM_USE_HOST_PTR传递给内核的变量的设备/主机内存一致性

aar*_*qli 7 opencl

如果使用CL_MEM_USE_HOST_PTR将变量传递给内核,是否意味着设备中变量的任何更改也会显示在主机内存中?

我在使用CPU作为设备而不是GPU的情况下,因此传递给内核的所有内容都将标记为CL_MEM_USE_HOST_PTR.

如果这是真的,那么我不再需要将所有内容都读回主机,这非常方便.

ala*_*and 10

您的理解是正确的,除了一个可能的陷阱:文档说明

允许OpenCL实现缓存host_ptr设备内存中指向的缓冲区内容.在设备上执行内核时,可以使用此缓存副本.

这意味着内核执行的数据更改可能不会立即反映出来host_ptr.实际上,在host_ptr用于缓冲区时,无法保证包含有效数据.

要获得有效和最新的数据,您必须强制同步.关于这个时刻,官方文档有点模糊,但缓冲映射/取消映射确定有效:

如果缓冲器对象与创建CL_MEM_USE_HOST_PTR设置在 mem_flags中,host_ptr在指定的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);
Run Code Online (Sandbox Code Playgroud)

  • 这是一个微妙的陷阱,我也被这个咬了,所以你提起这件事很好. (2认同)