假设我使用clEnqueueWriteBuffer
将数据复制到设备,并假设数据是RGB
值(unsigned char
s)的缓冲区。我想首先通过仅在输入缓冲区上操作(例如通过覆盖R
组件)将图像转换为灰度,然后我想将生成的图像调整为输出缓冲区。然后我会使用clEnqueueReadBuffer
将输出复制回主机内存。
由于我无法使用所有逻辑编写单个内核(由于OpenCL处理固有的无序性质),我正在考虑使用以下序列:clEnqueueWriteBuffer
- 两个clEnqueueNDRangeKernel
s - { {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原始图像和灰度调整大小的图像,则可以有两个输出(不改变原始图像)并且并行拥有两个命令队列以更快地完成整个作业(如果内核启动开销与内核相当)执行开销)但这需要两个队列的同步点,并且对于非常小的图像可能会变慢(一个队列需要从其他队列看到缓冲区副本,并且两个必须在以后完成以获得两个结果)。两个队列中的两个内核可以使用相同的缓冲区进行只读,没有任何问题。
在将命令排入队列之前,只注意为内核设置正确的参数(不能保证它们不会立即启动)
您可以根据需要使用尽可能多的内核执行,但设置参数不是队列操作,因此需要在开始时进行处理。