opencl - OpenCL 中的重叠传输和设备计算

标签 opencl gpgpu

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



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

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

谢谢。

编辑:更多信息

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

所以,我想将 MemInput 转换为 K1 的几个部分。
我想在主机上读取并保存 K2 处理的 MemOuput。

最佳答案

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

所有包含关键字 'enqueue' 的命令都有一个特殊的属性:这些命令不是直接执行的,而是当你使用 clFinish 触发它们时。 , clFlush , clEnqueueWaitForEvents , 使用 clEnqueueWriteBuffer在阻塞模式等等。

这意味着所有操作都同时发生,您必须使用事件对象对其进行同步。由于一切(可能)同时发生,您可以执行以下操作(每个点同时发生):

  • 传输数据 A
  • 处理数据 A 和传输数据 B
  • 处理数据 B & 传输数据 C & 检索数据 A'
  • 处理数据 C 和检索数据 B'
  • 检索数据 C'

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

    为了确保进程数据 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/

    相关文章:

    java - 如何使用JavaCL创建NVIDIA CUDA的CLContext?

    c++ - QGLWidget 获取 Windows 的 gl 上下文

    multithreading - 官方 OpenCL 2.2 标准是否支持 WaveFront?

    memory - 关于 OpenCL 中 cl_mem 的问题

    linux - 对 nvidia GPU 上的计算单元和预期核心的混淆

    xcode - 如何在 Xcode 4.1 中调试 OpenCL 内核?

    cuda - 在哪个设备上创建流与在哪个设备上执行代码之间是否存在关系?

    cuda - 是否有排序的atomicAdd或等效的

    ios - 关于 Metal 中线程组内存的问题

    parallel-processing - CUDA内核如何启动?