关于零拷贝的工作原理,我有点困惑.
1-要确认以下内容对应于opencl中的零拷贝.
.......................
. . .
. . .
. . CPU .
. SYSTEM . .
. RAM . c3 X .
. <=====> .
...|...................
PCI-E / /
| / /
c2 |X /PCI-E, CPU directly accessing GPU memory
| / / copy c3, c2 is avoided, indicated by X.
...|...././................
. MEMORY<====> .
. OBJECT .c1 .
. . GPU .
. GPU RAM . .
. . .
...........................
.......................
. . .
. . .
. . CPU .
.SYSTEM RAM . .
. . .
. . c3 .
. MEMORY<====> .
...| OBJECT............
| \ \
PCI-E \ \PCI-E, GPU directly accessing System memory. copy c2, c1 is avoided
| \ \
C2 |X \ \
...|.........\..\...........
. | . .
. <=======> .
. GPU c1 X GPU .
. RAM . .
. . .
............................
Run Code Online (Sandbox Code Playgroud)
GPU/CPU直接访问System/GPU-RAM,无需显式复制.
2 - 这有什么好处?PCI-e仍然限制了所有带宽.或者唯一的好处是我们可以在上述情况下避免复制c2和c1/c3?
KLe*_*ee1 15
您对零拷贝如何工作的理解是正确的.基本前提是您可以从设备访问主机内存,或从主机访问设备内存,而无需在中间执行中间缓冲步骤.
您可以通过使用以下标志创建缓冲区来执行零复制:
CL_MEM_AMD_PERSISTENT_MEM //Device-Resident Memory
CL_MEM_ALLOC_HOST_PTR // Host-Resident Memory
Run Code Online (Sandbox Code Playgroud)
然后,可以使用内存映射语义访问缓冲区:
void* p = clEnqueueMapBuffer(queue, buffer, CL_TRUE, CL_MAP_WRITE, 0, size, 0, NULL, NULL, &err);
//Perform writes to the buffer p
err = clEnqueueUnmapMemObject(queue, buffer, p, 0, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
使用零拷贝,您可以在执行以下操作的实现上实现性能:
相反,你可以一步完成所有这一切
在某些实现中,映射和取消映射的调用可以隐藏数据传输的成本.在我们的例子中,
如果实现以这种方式执行,那么使用映射方法将没有任何好处.但是,AMD更新的OpenCL驱动程序允许直接写入数据,使映射和取消映射的成本几乎为0.对于独立显卡,请求仍然通过PCIe总线进行,因此数据传输速度很慢.
然而,在APU架构的情况下,使用零拷贝语义的数据传输成本可以极大地提高由于APU独特架构而导致的传输速度(如下图所示).在此架构中,PCIe总线被统一北桥(UNB)取代,可实现更快的传输.
请注意,当使用内存映射的零拷贝语义时,从主机读取设备端缓冲区时,您将看到绝对可怕的带宽.这些带宽大约为0.01 Gb/s,很容易成为代码的新瓶颈.
对不起,如果这是太多的信息.这是我的论文题目.
归档时间: |
|
查看次数: |
3178 次 |
最近记录: |