为了减少我的应用程序从主机到设备的传输时间,我想使用固定内存。 NVIDIA's best practices guide建议使用以下代码映射缓冲区并写入数据:
cDataIn = (unsigned char*)clEnqueueMapBuffer(cqCommandQue, cmPinnedBufIn, CL_TRUE,CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, NULL);
for(unsigned int i = 0; i < memSize; i++)
{
cDataIn[i] = (unsigned char)(i & 0xff);
}
clEnqueueWriteBuffer(cqCommandQue, cmDevBufIn, CL_FALSE, 0,
szBuffBytes, cDataIn, 0, NULL, NULL);
Intel's optimization guide建议使用对clEnqueueMapBuffer和clEnqueueUnmapBuffer的调用,而不是对clEnqueueReadBuffer或clEnqueueWriteBuffer的调用。
使用固定内存/映射内存的正确方法是什么?是否有必要使用enqueueWriteBuffer写入数据或者enqueueMapBuffer是否足够?
另外,CL_MEM_ALLOC_HOST_PTR和CL_MEM_USE_HOST_PTR有什么区别?
答案 0 :(得分:13)
这是一个很有趣的话题,很少有人详细介绍。 我将尝试准确定义它的工作原理。
固定存储器指的是存储器以及存储器中存在的存储器,因此可以在这两个存储器之间进行DMA写入。提高复制性能。
这就是它在缓冲区创建参数中需要CL_MEM_ALLOC_HOST_PTR
的原因。
另一方面,CL_MEM_USE_HOST_PTR
将使用主机指针来创建缓冲区,规范还不清楚这是否可以是固定内存。但一般来说,它不应该以这种方式创建固定内存,因为主机指针尚未被OpenCL API保留,并且不清楚它驻留在内存中的位置。
关于地图/阅读问题。 两者都可以。他们将提供相同的表现。 这两种技术之间的区别在于:
buffer+Mapped_Buffer
。好消息是你现在可以只clEnqueueRead/Write
到那个映射指针。 API将等待固定数据保持一致,然后考虑完成。它更容易使用,因为它就像一次性执行map + unmap。 读/写模式更易于使用,特别适用于重复读取,但不像手动地图选项那样通用,因为您不能写read only
地图,也不能读{{1} }地图。但是对于一般用途,永远不会写入读取的变量,反之亦然。
我的理解是英特尔建议,指的是“使用地图,而不是简单的读/写”,而不是“当你使用地图时,不要使用地图上的读/写指针“即可。
您是否通过英特尔硬件检查此nVIDIA推荐?我认为它应该有效,但是我不知道该操作是否确实是最佳的(如在AMD或nVIDIA HW中)。