OpenCL是否可以通过多个命令队列来保证缓冲存储器的完整性?

时间:2019-03-07 20:28:09

标签: gpu opencl

简化的问题 我有两个主机线程,每个线程都具有通往同一GPU设备的命令队列。这两个队列都是乱序的,执行顺序是使用等待事件显式管理的(简化示例不需要此,但实际应用程序需要)。

ThreadA是一种轻量级的处理管道,可在获取新数据时实时运行。 ThreadB是重量级的较慢的处理管道,它使用相同的输入数据,但以较慢的速率异步处理它。我正在使用一个双缓冲区来保持管线分开,但允许ThreadB处理ThreadA写入设备的相同输入数据。

ThreadA的循环:

  1. 从网络中提取图像作为数据
  2. 使用cl_mem BufferA将图像写入设备clEnqueueWriteBuffer(CommandQueueA)
  3. 写入完成(内核将结果输出到KernelA后,使用clEnqueueNDRangeKernel(CommandQueueA)调用图像处理cl_mem OutputA
  4. 使用OutputAclEnqueueReadBuffer(CommandQueueA)读取处理后的结果

ThreadB的循环

  1. 等到时间用完(以较低的速度工作)
  2. 使用BufferA(双缓冲区交换)将BufferB复制到clEnqueueCopyBuffer(CommandQueueB)
  3. 复制完成后,使用KernelB调用clEnqueueNDRangeKernel(CommandQueueB)进行较慢的图像处理(内核将结果输出到cl_mem OutputB
  4. 使用OutputBclEnqueueReadBuffer(CommandQueueB)读取处理后的结果

我的问题

ThreadA的第2步和ThreadB的第2步之间存在潜在的竞争条件。我不在乎哪个先执行,我只想确保不复制将BufferA写入BufferBBufferA

  1. OpenCL是否提供任何不会发生这种情况的隐式保证?
  2. 如果不是,则如果我改为在ThreadB的第2步上使用clEnqueueCopyBuffer(CommandQueueA),以便将写操作和复制操作都放在同一命令队列中,是否可以确保即使在同一时间它们也不能同时运行队列是否允许乱序执行?
  3. 如果没有,是否有比将ThreadA中的WriteBuffer事件添加到ThreadB中的CopyBuffer命令的等待列表更好的解决方案?

似乎所有这些都应该起作用,但是我在OpenCL规范中找不到它说的很好。如果可能,请在您的答案中引用OpenCL规范。

1 个答案:

答案 0 :(得分:2)

  

OpenCL是否提供任何暗示保证不会发生这种情况?

否,除非您使用单个顺序命令队列,否则没有隐式同步。

  

如果没有,如果我改为在ThreadB步骤2上使用   clEnqueueCopyBuffer(CommandQueueA)以便写和写   复制操作在同一命令队列中,   确保即使   队列是否允许乱序执行?

否,无论队列的类型如何(顺序与无序), OpenCL运行时不跟踪以下项的内存依赖性 命令。用户负责在等待列表中指定事件, 如果命令之间存在任何依赖关系。

以下引用可以证明这一点:

  

s3.2.1执行模型:上下文和命令队列

     

乱序执行:命令按顺序发出,但是可以   在执行以下命令之前不要等待完成。任何   订单约束由程序员通过   显式同步命令。

这不是您问题的直接答案,但我认为如果 提供了任何担保,在此应提及 部分。

  

如果没有,是否有比添加   ThreadA中WriteBuffer的事件到   ThreadB中的CopyBuffer命令?

如果您可以使用单个顺序队列,则可能是 至少比某些情况比跨队列事件更有效 实施。