OpenCL:clSetKernelArg 与 clSetKernelArg + clEnqueueWriteBuffer

OpenCL: clSetKernelArg vs. clSetKernelArg + clEnqueueWriteBuffer

关于 OpenCL 缓冲区传输的问题: 我想将缓冲区 (cl_mem) 从主机传递给内核(即传递给设备)。 有两个宿主函数:

我使用 clSetKernelArg 将我的缓冲区传递给内核参数之一。但这是否意味着缓冲区自动传输到设备? 此外,还有将缓冲区写入设备的函数 clEnqueueWriteBuffer。

我的问题:对于我的用例(将缓冲区传递给内核),使用(a.)仅 clSetKernelArg 或(b.)clSetKernelArg 和 clEnqueueWriteBuffer 有什么不同吗?

您必须在将内核排队执行之前调用这两个函数。

clSetKernelArg

Used to set the argument value for a specific argument of a kernel.

这个只设置参数,例如一些指针,用于被调用的内核。 没有隐式数据传输


考虑以下示例:

  • 相同的内存对象被用作不同内核的参数
    • => 只需要一次写入设备;但是要为不同的内核设置多个参数
  • 同一个内核可以多次使用不断变化的输入内存对象
    • => 每次调用一次写入;但内核参数只设置一次
  • 可以使用 clSetKernelArg() 在同一内核的两次调用之间切换读取和写入缓冲区(双缓冲)
    • => 可能没有传输,或者只有每 n 次迭代;但是在每次调用之前设置了两个参数

总的来说:主机和计算设备之间的数据传输非常昂贵,因此应该避免,最好通过明确触发它们来实现。