随着AMD Kaveri和Intel第四代CPU的出现,CPU和GPU硬件的统一正在不断推进,这可以通过hUMA(异构统一内存访问)来证明。这应该允许在CPU和GPU之间进行无需复制的数据共享。我想知道,最新的OpenCL(或其他GPGPU框架)实现是否允许在运行在CPU和GPU上的代码之间进行真正的无需复制(没有显式或隐式数据复制)的大型数据结构共享。
随着AMD Kaveri和Intel第四代CPU的出现,CPU和GPU硬件的统一正在不断推进,这可以通过hUMA(异构统一内存访问)来证明。这应该允许在CPU和GPU之间进行无需复制的数据共享。我想知道,最新的OpenCL(或其他GPGPU框架)实现是否允许在运行在CPU和GPU上的代码之间进行真正的无需复制(没有显式或隐式数据复制)的大型数据结构共享。
CL_MEM_ALLOC_HOST_PTR
标志,主机和设备之间可以共享数据而无需进行任何内存传输。此标志会为设备分配一个缓冲区,但确保其位于主机也可以访问的存储器中。这些“零复制”传输的工作流通常采用以下形式:// Allocate a device buffer using host-accessible memory
d_buffer = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, size, NULL, &err);
// Get a host-pointer for the buffer
h_buffer = clEnqueueMapBuffer(queue, d_buffer, CL_TRUE, CL_MAP_WRITE,
0, size, 0, NULL, &err);
// Write data into h_buffer from the host
...
// Unmap the memory buffer
clEnqueueUnmapMemObject(queue, d_buffer, h_buffer, 0, NULL, NULL);
// Do stuff with the buffer on the device
clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_buffer);
clEnqueueNDRangeKernel(queue, kernel, ...);
clSVMAlloc
分配一个缓冲区,它将返回一个在主机和设备上都有效的指针。当您希望从主机访问缓冲区时,您将使用clEnqueueSVMMap
和clEnqueueSVMUnmap
同步数据,并使用clSetKernelArgSVMPointer
将其传递给设备。SVM和CL_MEM_ALLOC_HOST_PTR
之间的关键区别在于,SVM指针也可以包含在传递给设备的另一个缓冲区内(例如,包含在结构体内或由另一个指针指向)。这就是允许您构建可在主机和设备之间共享的复杂基于指针的数据结构的原因。CL_MEM_ALLOC_HOST_PTR
)已知可与许多市场上已有几年的设备配合使用(AMD APU、Intel IGPUs、所有移动GPU)。我自己在2011年就曾在第一批AMD融合设备上使用过这个方法。因此,如果您只需要共享平面数据结构,那么这是一种经过验证的方法,已经得到许多实现的支持。 - jprice