OpenCL:通过CL_MEM_USE_Host_PTR传递到内核的变量的设备/主机内存一致性

OpenCL:通过CL_MEM_USE_Host_PTR传递到内核的变量的设备/主机内存一致性,opencl,Opencl,如果使用CL_MEM_USE_HOST_PTR将变量传递给内核,是否意味着对设备中变量的任何更改也会显示在主机内存中 我所处的场景是使用CPU作为设备而不是GPU,因此传递到内核的所有内容都将标记为CL_MEM_USE_HOST_PTR 如果这是真的,那么我就不再需要把所有的内容都读回主机,这非常方便。您的理解是正确的,除了一个可能的陷阱:声明 允许OpenCL实现缓存缓冲区内容 由设备内存中的主机ptr指向。可以使用此缓存副本 当内核在设备上执行时 这意味着内核对数据所做的更改可能不会立即反映

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

我所处的场景是使用CPU作为设备而不是GPU,因此传递到内核的所有内容都将标记为CL_MEM_USE_HOST_PTR


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

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

允许OpenCL实现缓存缓冲区内容 由设备内存中的主机ptr指向。可以使用此缓存副本 当内核在设备上执行时

这意味着内核对数据所做的更改可能不会立即反映在
host\u ptr
中。事实上,不能保证
host_ptr
在用作缓冲区时包含有效数据

为了获得有效且最新的数据,必须强制同步。官方文件对这一时刻有点含糊不清,但确实有效:

如果创建缓冲区对象时设置了
CL\u MEM\u USE\u HOST\u PTR
mem_flags
,在
clCreateBuffer
中指定的
host_ptr
保证 包含映射时要映射的区域中的最新位
clEnqueueMapBuffer
命令已完成;和指针值 由
clEnqueueMapBuffer返回的
将从
host\u ptr
在创建缓冲区对象时指定

以下是改编自以下内容的示例:


这是一个微妙的骗局,我也被它咬了,所以你把这个提出来很好。@Alan我想我问得很晚了。。但是,如果我正在使用事件等待,而不是映射内存。。它会更新主机设备中的正确阵列吗?对我来说,它正在工作(可能是我正在使用事件让内核完成)。但是,我可以跳过映射吗?@Vishwadeep只是等待内核完成执行。你的方法可能会奏效,特别是如果你只使用CPU作为计算设备,但这仍然是未定义的行为。谢谢你的回答。
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);