正如您可能已经看到的那样,您可以通过使用clEnqueueWriteBuffer
和类似的方式从主机传输到设备。
所有带有关键字 'enqueue' 的命令都有一个特殊的属性:这些命令不是直接执行的,而是当你使用clFinish
、clFlush
、clEnqueueWaitForEvents
、clEnqueueWriteBuffer
在阻塞模式下使用等等来触发它们时。
这意味着所有动作同时发生,您必须使用事件对象同步它。由于一切(可能)同时发生,您可以执行以下操作(每个点同时发生):
- 传输数据 A
- 处理数据 A 和传输数据 B
- 处理数据 B & 传输数据 C & 检索数据 A'
- 处理数据 C & 检索数据 B'
- 检索数据 C'
请记住:没有事件对象的入队任务可能会导致所有入队元素的同时执行!
为确保流程数据 B 不会在传输 B 之前发生,您必须从中检索事件对象clEnqueueWriteBuffer
并将其作为对象提供以等待 ficlEnqueueNDRangeKernel
cl_event evt;
clEnqueueWriteBuffer(... , bufferB , ... , ... , ... , bufferBdata , NULL , NULL , &evt);
clEnqueueNDRangeKernel(... , kernelB , ... , ... , ... , ... , 1 , &evt, NULL);
每个命令当然可以等待某些对象并生成一个新的事件对象,而不是提供 NULL。最后一个参数是一个数组,所以你可以事件等待几个事件!
编辑:总结下面的评论
传输数据-什么命令在哪里起作用?
CPU 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
* 您可以通过使用参数提供数据直接初始化缓冲区。