Memory 如何在OpenCL中使用固定内存/映射内存

Memory 如何在OpenCL中使用固定内存/映射内存,memory,opencl,gpu,gpgpu,data-transfer,Memory,Opencl,Gpu,Gpgpu,Data Transfer,为了减少应用程序从主机到设备的传输时间,我想使用固定内存。建议使用以下代码映射缓冲区并写入数据: 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] = (uns

为了减少应用程序从主机到设备的传输时间,我想使用固定内存。建议使用以下代码映射缓冲区并写入数据:

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);
cDataIn=(unsigned char*)clenqueueemapbuffer(cqCommandQue,cmPinnedBufIn,CL\u TRUE,CL\u MAP\u WRITE,0,memSize,0,NULL,NULL,NULL);
for(无符号整数i=0;i
建议使用对clEnqueueMapBuffer和CLENQUEUNMAPBUFFER的调用,而不是对CLENQUEUREADBUFFER或clEnqueueWriteBuffer的调用

使用固定内存/映射内存的正确方法是什么?是否需要使用enqueueWriteBuffer写入数据,或者enqueueMapBuffer是否足够


此外,CL_MEM_ALLOC_HOST_PTR和CL_MEM_USE_HOST_PTR之间有什么区别?

这是一个有趣的话题,很少有人详细介绍。 我将尝试准确地定义它是如何工作的

固定内存指的是主机中存在的内存以及设备中的内存,因此这两个内存之间可以进行DMA写入。提高拷贝性能。 这就是为什么在缓冲区创建参数中需要
CL_MEM_ALLOC_HOST_PTR

另一方面,
CL\u MEM\u USE\u HOST\u PTR
将使用主机指针创建缓冲区,规范不清楚这是否可以是固定内存。但一般来说,它不应该是以这种方式创建的固定内存,因为主机指针没有被OpenCLAPI保留,也不清楚它在内存中的位置


关于地图/阅读问题两者都可以。他们也会有同样的表现。 这两种技术的区别在于:

  • 对于映射/取消映射:您需要在写入/读取之前映射,然后取消映射。这样可以确保数据的一致性。这些都是API调用,需要时间来完成,而且是异步的。好的是,除了缓冲区对象之外,您不需要保存任何其他对象
  • 对于Map+Read/Write:在创建内存区域时,需要进行映射并保存指针值。然后,在销毁缓冲区时,您需要先取消映射,然后再销毁它。您需要始终按住
    buffer+Mapped\u buffer
    。好的是,您现在可以
    clEnqueueRead/Write
    到映射指针。API将等待被钉扎的数据是一致的,然后考虑它完成了。它更容易使用,因为它就像一次完成贴图+取消贴图一样
读/写模式更易于使用,特别是对于重复读取,但不如手动映射选项那样通用,因为您既不能编写
只读
映射,也不能读取
只写
映射。但对于一般用途,读取的变量永远不会被写入,反之亦然


我的理解是,“英特尔建议”是指“使用映射,而不是普通的读/写”
,而不是“使用映射时,不要在映射指针上使用读/写”


您是否通过英特尔硬件检查了此nVIDIA建议?我认为它应该可以工作,但我不知道操作是否确实是最佳的(如AMD或nVIDIA HW)。

很奇怪,您需要使用clEnqueueWriteBuffer()和Map/Unmap。因为当您进行映射,然后更改主机指针时,实际上是在更改CPU和GPU数据。当您执行取消映射时,数据将在CPU和GPU端之间同步。我不明白您是否需要在映射+更改CDATA IN和取消映射之间执行clEnqueueWriteBuffer。很奇怪。。。