【问题标题】:Commenting clfinish() out makes program %100 faster注释掉 cfinish() 会使程序 %100 更快
【发布时间】:2013-08-28 09:36:51
【问题描述】:

我有一个 opencl 内核批处理类,它使 40 多个内核入队,并且每次内核执行之间都有一个 clFinish()。

问题:当我注释掉 clFinish()s 然后程序运行速度提高 %100 时,这是否意味着当内核使用相同的缓冲区进行写入和读取时存在未定义的行为?我怀疑性能提升来自更好地利用 gpu/占用资源。使用 按顺序命令队列 是否可以保证两个内核之间存在屏障,或者我是否需要在它们之间使用 clFinish()?

它是一个简单的物理模型,两个版本之间没有明显的区别。

也许我只需要在最后使用 clFinish() ?

编辑:此命令队列未使用 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE。

【问题讨论】:

  • 能发一些主机代码吗?

标签: opencl


【解决方案1】:

如果所有内核调用都在同一个命令队列上执行并且这是一个有序队列,那么您不需要在内核调用之间使用clFinish,这正是您的场景,因此您不需要所有这些clFinish调用,只保留最后一个。

性能差异来自以下几点:

  • 每个clFinish 调用都存在开销,用于将所有排队的命令发送到设备并检查它们的执行状态。
  • 这些clFinish 调用也会中断GPU 正在完成的工作——GPU 必须等待下一个内核入队并在clFinish 之后发送到设备。省略对 clFinish 的调用意味着内核调用会在之前的内核仍在执行时发送到 GPU。

【讨论】:

  • 是的,都在同一个队列中。谢谢。
【解决方案2】:

也许内核没有运行?将内核排队很便宜,并且不需要主机方面的任何努力。但是,调用 clEnqeueNDRangeKernel != 运行内核。

//Start host timer
clEnqueNDRangeKernel(...);
//Stop host timer - this doesn't actually time the kernel on the host

对比

//Start host timer
clEnqueueNDRangeKernel(...);
clFinish();
//Stop host timer - this does time the kernel on the host

或者,您可以使用内核分析和事件。

【讨论】:

  • 绝对有效点,需要检查每个 OpenCL 函数调用的错误状态,例如内核执行错误可能仅表现为稍后的clFinish 返回的错误代码。
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2014-01-08
  • 1970-01-01
  • 2019-05-14
  • 2023-01-30
  • 2010-09-21
相关资源
最近更新 更多