在使用OpenCL或其他GPU框架的现代x86硬件上,CPU和GPU之间共享数据

在使用OpenCL或其他GPU框架的现代x86硬件上,CPU和GPU之间共享数据,opencl,gpgpu,Opencl,Gpgpu,如AMD Kaveri与hUMA(异构统一内存访问)和Intel第四代CPU所证明的,CPU和GPU硬件的逐步统一应允许CPU和GPU之间的数据无拷贝共享。我想知道,最新的OpenCL(或其他GPGPU框架)实现是否允许真正的无拷贝共享(无显式或隐式数据复制)在CPU和GPU上运行的代码之间的大型数据结构。OpenCL从1.0版开始,通过CL\u MEM\u ALLOC\u host\u PTR标志,在主机和设备之间共享数据的能力已可用。此标志为设备分配缓冲区,但确保它位于主机也可以访问的内存中

如AMD Kaveri与hUMA(异构统一内存访问)和Intel第四代CPU所证明的,CPU和GPU硬件的逐步统一应允许CPU和GPU之间的数据无拷贝共享。我想知道,最新的OpenCL(或其他GPGPU框架)实现是否允许真正的无拷贝共享(无显式或隐式数据复制)在CPU和GPU上运行的代码之间的大型数据结构。

OpenCL从1.0版开始,通过
CL\u MEM\u ALLOC\u host\u 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, ...);
这将创建一个设备缓冲区,从主机向其中写入一些数据,然后在设备上使用该缓冲区运行内核。由于缓冲区的分配方式,如果设备和主机具有统一的内存系统,则不会导致内存传输


上述方法仅限于简单的平面数据结构(1D阵列)。如果您对使用更复杂的东西感兴趣,例如链表、树或任何其他基于指针的数据结构,则需要利用OpenCL 2.0中的共享虚拟内存(SVM)功能。在撰写本文时,AMD和Intel都发布了一些对OpenCL2.0功能的预览支持,但我不能保证他们的SVM实现


SVM方法的工作流程与上面列出的代码有些类似。简而言之,您将使用
clSVMAlloc
分配一个缓冲区,它将返回一个在主机和设备上都有效的指针。当您希望从主机访问缓冲区时,您将使用
clEnqueueSVMMap
clenqueuesvunmap
同步数据,并使用
clSetKernelArgSVMPointer
将数据传递到设备。SVM与CL_MEM_ALLOC_HOST_PTR之间的关键区别在于,SVM指针也可以包含在传递给设备的另一个缓冲区内(例如,在结构内或由另一个指针指向)。这就是允许您构建复杂的基于指针的数据结构,可以在主机和设备之间共享。

AMD APU和Intel Integrated Graphics都允许OpenCL内核访问主内存,而无需任何副本。@Dithermaster您是否确实知道特定的OpenCL实现在特定的应用程序上实际上是以这种方式运行的硬件?相当肯定。我要看供应商文档。两个供应商都有文档描述了在分配缓冲区时要使用哪些标志,然后使用不会产生副本的ClenqueueEmapBuffer。由于这两个设备与CPU共享相同的内存,因此它们能够做到这一点是有意义的。这和支持向量机的区别在于,使用支持向量机,缓冲区可以包含在GPU端有效的指针。感谢您提供信息性的帖子<代码>OpenCL从1.0版开始提供了在主机和设备之间共享数据而无需任何内存传输的功能理论上是的,但当时没有硬件能够支持该功能而无需通过PCIe总线向GPU发送数据。你文章的第二部分更接近于回答我的问题,但正如你所写,我们还不知道未发布产品的细节。我的问题是是否存在具有特定行为(共享数据无内存传输)的实现,而不是OpenCL的理论功能。@PaulJurczak只是想澄清一下,我描述的第一种方法(
CL\u MEM\u ALLOC\u HOST\u PTR
)是已知的,它可以与市场上已经上市几年的所有设备一起工作(AMD APU、Intel IGPUs、全移动GPU)。我自己在2011年第一台AMD fusion设备上就使用了这种方法。因此,如果您只需要共享平面数据结构,这是一种经过尝试和测试的方法,已经得到了许多实现的支持。
已知可以与大量设备一起工作。
:这就是我一直在寻找的,谢谢。