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

时间:2017-04-04 13:13:39

标签: c++ opencl gpgpu simd

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

由于我无法使用所有逻辑编写单个内核(由于OpenCL处理固有的无序性质),我正在考虑使用以下序列:clEnqueueWriteBuffer - 两个clEnqueueNDRangeKernel s - { {1}}。

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

1 个答案:

答案 0 :(得分:1)

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

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

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

它说

  

例如,如果应用程序调用clEnqueueNDRangeKernel   执行内核A,然后执行clEnqueueNDRangeKernel   在内核B中,应用程序可以假设内核A首先完成并且   然后执行内核B.如果内核对象由内核A输出   是内核B的输入,然后内核B将看到正确的数据   通过执行内核A生成的内存对象。如果

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

如果要同时使用greyscaled原始图像和灰度调整大小的图像,则可以有两个输出(不改变原始图像)并且并行拥有两个命令队列以更快地完成整个作业(如果内核启动开销与内核相当)执行开销)但这需要两个队列的同步点,并且对于非常小的图像可能会变慢(一个队列需要从其他队列看到缓冲区副本,并且两个必须在以后完成以获得两个结果)。两个队列中的两个内核可以使用相同的缓冲区进行只读,没有任何问题。

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

您可以根据需要使用尽可能多的内核执行,但设置参数不是队列操作,因此需要在开始时进行处理。