在OpenCL中重叠传输和设备计算

Ale*_*cet 8 gpgpu opencl

我是OpenCL的初学者,我很难理解某些东西.我想改善主机和设备之间的图像传输.我制定了一个更好地了解我的计划.

顶部:我现在拥有的东西 底部:我想要的是HtD(主机到设备)和DtH(设备到主机)是内存传输.K1和K2是内核.

我想过使用映射内存,但第一次传输(Host to Device)是用clSetKernelArg()命令完成的,不是吗?或者我是否必须将输入图像剪切为子图像并使用映射来获取输出图像?

谢谢.

编辑:更多信息

K1处理mem输入图像.K2处理来自K1的输出图像.

所以,我想将MemInput转移到K1的几个部分.我想在主机上读取并保存由K2处理的MemOuput.

Nip*_*pey 6

正如您可能已经看到的那样,您可以使用clEnqueueWriteBuffer和类似的方式从主机到设备进行传输.

具有他们的关键字是"排队"的所有命令有一个特殊的属性:命令是不能直接执行,但是当你跳跳虎他们使用clFinish,clFlush,clEnqueueWaitForEvents,使用clEnqueueWriteBuffer阻塞模式和更多一些.

这意味着所有操作都会立即发生,您必须使用事件对象进行同步.当所有事情(可能)同时发生时,你可以做这样的事情(每个点同时发生):

  1. 转移数据A.
  2. 过程数据A和传输数据B.
  3. 流程数据B和传输数据C&Retrive Data A'
  4. 处理数据C和检索数据B'
  5. 检索数据C'

记住:没有事件对象的排队任务可能导致所有入队元素的同时执行!

为了确保在传输B之前不发生过程数据B,您必须从中检索事件对象clEnqueueWriteBuffer并将其作为对象提供,以等待传输clEnqueueNDRangeKernel

cl_event evt;
clEnqueueWriteBuffer(... , bufferB , ... , ... , ... , bufferBdata , NULL , NULL , &evt);
clEnqueueNDRangeKernel(... , kernelB , ... , ... , ... , ... , 1 , &evt, NULL);
Run Code Online (Sandbox Code Playgroud)

每个命令当然可以等待某些对象并生成新的事件对象,而不是提供NULL.最后一个参数是一个数组,所以你可以事件等待几个事件!


编辑:总结以下评论 传输数据 - 什么命令在哪里行动?

       CPU                        GPU
                            BufA       BufB
array[] = {...}
clCreateBuffer()  ----->  [     ]              //Create (empty) Buffer in GPU memory *
clCreateBuffer()  ----->  [     ]    [     ]   //Create (empty) Buffer in GPU memory *
clWriteBuffer()   -arr->  [array]    [     ]   //Copy from CPU to GPU
clCopyBuffer()            [array] -> [array]   //Copy from GPU to GPU
clReadBuffer()    <-arr-  [array]    [array]   //Copy from GPU to CPU

*您可以通过使用host_ptr参数提供数据来直接初始化缓冲区.