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

5

随着AMD Kaveri和Intel第四代CPU的出现,CPU和GPU硬件的统一正在不断推进,这可以通过hUMA(异构统一内存访问)来证明。这应该允许在CPU和GPU之间进行无需复制的数据共享。我想知道,最新的OpenCL(或其他GPGPU框架)实现是否允许在运行在CPU和GPU上的代码之间进行真正的无需复制(没有显式或隐式数据复制)的大型数据结构共享。


AMD APU和Intel集成显卡都允许OpenCL内核直接访问主存,无需进行任何复制操作。 - Dithermaster
@Dithermaster 你确定一种特定的OpenCL实现在特定硬件上会表现出这种行为吗? - Paul Jurczak
1
相当确定。我正在按照供应商文档进行操作。两个供应商都有描述在分配缓冲区时使用哪些标志,然后使用clEnqueueMapBuffer来避免复制的文档。由于两个设备与CPU共享同一内存,因此这是有道理的。这与SVM的区别在于,使用SVM的缓冲区可以包含在GPU端有效的指针。 - Dithermaster
1个回答

5
从OpenCL 1.0版本开始,通过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, ...);

这将创建一个设备缓冲区,从主机中向其中写入一些数据,然后在设备上使用该缓冲区运行内核。由于分配缓冲区的方式,如果设备和主机具有统一的内存系统,则不会导致内存传输。
上述方法仅适用于简单的平面数据结构(1D数组)。如果您想处理一些更复杂的东西,如链表、树或任何其他基于指针的数据结构,您需要利用OpenCL 2.0中的共享虚拟内存(SVM)功能。在撰写本文时,AMD和英特尔均发布了一些OpenCL 2.0功能的预览支持,但我无法保证它们对SVM的实现。
使用SVM方法的工作流程与上面列出的代码类似。简而言之,您将使用clSVMAlloc分配一个缓冲区,它将返回一个在主机和设备上都有效的指针。当您希望从主机访问缓冲区时,您将使用clEnqueueSVMMapclEnqueueSVMUnmap同步数据,并使用clSetKernelArgSVMPointer将其传递给设备。SVM和CL_MEM_ALLOC_HOST_PTR之间的关键区别在于,SVM指针也可以包含在传递给设备的另一个缓冲区内(例如,包含在结构体内或由另一个指针指向)。这就是允许您构建可在主机和设备之间共享的复杂基于指针的数据结构的原因。

感谢您提供的信息丰富的帖子。从OpenCL 1.0版本开始,主机和设备之间共享数据而无需进行任何内存传输的能力在理论上是可行的。但实际上,在当时没有硬件能够支持此功能,除非通过PCIe总线将数据发送到GPU。您帖子的第二部分更接近回答我的问题,但正如您所写的那样,我们还不知道未发布产品的详细信息。我的问题是关于具有特定行为(共享数据无需内存传输)的实现是否存在,而不是OpenCL的理论能力。 - Paul Jurczak
1
@PaulJurczak 只是为了澄清,我描述的第一种方法(CL_MEM_ALLOC_HOST_PTR)已知可与许多市场上已有几年的设备配合使用(AMD APU、Intel IGPUs、所有移动GPU)。我自己在2011年就曾在第一批AMD融合设备上使用过这个方法。因此,如果您只需要共享平面数据结构,那么这是一种经过验证的方法,已经得到许多实现的支持。 - jprice
“is known to work with a whole bunch of devices”:这正是我在寻找的,谢谢。 - Paul Jurczak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接