我是 OpenCL 的初学者,我很难理解某些东西。
我想改进主机和设备之间的图像传输。
我制定了一个计划以更好地了解我。
顶部:我现在拥有的 |底部:我想要的
HtD(主机到设备)和 DtH(设备到主机)是内存传输。
K1 和 K2 是内核。
我想过使用映射内存,但是第一次传输(主机到设备)是使用 clSetKernelArg() 命令完成的,不是吗?
或者我是否必须将我的输入图像切割成子图像并使用映射来获取输出图像?
谢谢。
编辑:更多信息
K1 处理 mem 输入图像。
K2 处理来自 K1 的输出图像。
所以,我想将 MemInput 转换为 K1 的几个部分。
我想在主机上读取并保存 K2 处理的 MemOuput。
最佳答案
正如您可能已经看到的,您可以使用 clEnqueueWriteBuffer
从主机到设备进行传输。和类似的。
所有包含关键字 'enqueue' 的命令都有一个特殊的属性:这些命令不是直接执行的,而是当你使用 clFinish
触发它们时。 , clFlush
, clEnqueueWaitForEvents
, 使用 clEnqueueWriteBuffer
在阻塞模式等等。
这意味着所有操作都同时发生,您必须使用事件对象对其进行同步。由于一切(可能)同时发生,您可以执行以下操作(每个点同时发生):
请记住:没有事件对象的入队任务可能会导致所有入队元素同时执行!
为了确保进程数据 B 不会在传输 B 之前发生,您必须从
clEnqueueWriteBuffer
检索事件对象。并将其作为等待 f.i. 的对象提供。 clEnqueueNDRangeKernel
cl_event evt;
clEnqueueWriteBuffer(... , bufferB , ... , ... , ... , bufferBdata , NULL , NULL , &evt);
clEnqueueNDRangeKernel(... , kernelB , ... , ... , ... , ... , 1 , &evt, NULL);
每个命令当然可以等待某些对象并生成新的事件对象,而不是提供 NULL。 last 旁边的参数是一个数组,因此您可以事件等待多个事件!
编辑:总结下面的评论
传输数据 - 什么命令作用在哪里?
中央处理器 GPU
BufA BufB
数组[] = {...}
clCreateBuffer() -----> [ ]//在GPU内存中创建(空)Buffer *
clCreateBuffer() -----> [ ] [ ]//在GPU内存中创建(空)Buffer *
clWriteBuffer() -arr-> [array] [ ]//从CPU复制到GPU
clCopyBuffer() [array] -> [array]//从GPU复制到GPU
clReadBuffer() <-arr- [array] [array]//从GPU复制到CPU
* 您可以通过使用
host_ptr
提供数据来直接初始化缓冲区范围。
关于opencl - OpenCL 中的重叠传输和设备计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12389321/