c++ - 我可以在相同的设备缓冲区上一个接一个地调用 OpenCL 内核吗?

标签 c++ opencl gpgpu simd

假设我使用 clEnqueueWriteBuffer 将数据复制到设备,并假设数据是 RGB 值(unsigned char)的缓冲区。我想首先通过仅对输入缓冲区进行操作(例如通过覆盖 R 组件)将图像转换为灰度,然后我想将生成的图像调整为输出缓冲区。然后我会使用 clEnqueueReadBuffer 将输出复制回主机内存。

由于我无法编写包含所有逻辑的单个内核(因为 OpenCL 处理的固有无序性质),我正在考虑使用以下序列:clEnqueueWriteBuffer - 两个 clEnqueueNDRangeKernels - clEnqueueReadBuffer

这种方法是否正确?我可以在规范的哪个位置找到这方面的更多详细信息?

最佳答案

如果所有命令都在同一个命令队列上,并且命令队列是有序类型,那么它就可以工作。

有序队列按顺序执行所有命令。每个命令都会看到它之前的最新命令的结果。

这里: https://www.khronos.org/registry/OpenCL/sdk/1.0/docs/man/xhtml/clCreateCommandQueue.html

它说

For example, if an application calls clEnqueueNDRangeKernel to execute kernel A followed by a clEnqueueNDRangeKernel to execute kernel B, the application can assume that kernel A finishes first and then kernel B is executed. If the memory objects output by kernel A are inputs to kernel B then kernel B will see the correct data in memory objects produced by execution of kernel A. If the


注意:如果您不使用原始灰度并且它是缩小而不是放大,则在调整大小后应用灰度可能会更有效。如果只需要调整大小的图像灰度化,您也可以在单个内核中同时执行这两项操作。当 re-size workitem 为结果像素选择一些像素时,您可以在结果像素上应用灰度。

如果你打算同时使用灰度原始图像和灰度调整大小的图像,你可以有两个输出(不改变原始图像)并有两个并行的命令队列来更快地完成整个工作(如果内核启动开销与内核相当)执行开销)但这将需要两个队列的同步点,并且对于非常小的图像可能会变慢(一个队列需要查看来自其他队列的缓冲区拷贝,并且两者都必须稍后完成才能获得两个结果)。来自两个队列的两个内核可以使用相同的只读缓冲区,没有任何问题。

只注意在将命令入队之前为内核设置正确的参数(不能保证它们不会立即启动)

您可以根据需要执行任意数量的内核执行,但设置参数不是队列操作,因此需要在开始时注意。

关于c++ - 我可以在相同的设备缓冲区上一个接一个地调用 OpenCL 内核吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43208311/

相关文章:

OpenCL:如何在上下文中选择 GPU

c++ - 在 GPU 上计算积分图像真的比在 CPU 上更快吗?

cuda - GPU 的每个多处理器有多少个 'CUDA cores'?

c++ - 指向限定和非限定类型表示的指针

c++ - avcodec_receive_packet 中的错误(gdi screenshot + ffmpeg)

c++ - 键鼠监听,自动化

c++ - 如何在进程间通信中获取其他端点的进程ID

c++ - 在 Ubuntu Linux 中使用 Nvidia 卡的 OpenCL 出现 -1001 错误

c++ - Opencv-ocl 可以用不同的硬件执行吗?

cuda - 多 GPU 与 CUDA Thrust 的使用