0

我的 OpenCL 程序(不要害怕,这是为 3D CFD 自动生成的代码)表现出奇怪的行为——在 opencl_enq_job_* 程序 (opencl_code.c) 中花费了大量时间,其中只有异步 OpenCL 命令:

clEnqueueWriteBuffer(..,CL_FALSE,...,&event1);
clSetKernelArg(...);
...
clEnqueueNDRangeKernel(...,1,&event1,&event2);
clEnqueueReadBuffer(...,CL_FALSE,...,1,&event2,&event3);
clSetEventCallback(event3,...);
clFlush(...);

在程序输出中,opencl_enq_job_*所花费的时间如下:

OCL废品:0.60456248727985751

这意味着在该程序中浪费了 60% 的时间。

大部分时间(92%)花在 clEnqueueReadBuffer 函数上,约 5% 用在 clSetEventCallback 上。

为什么这么多?这段代码有什么问题?

我的配置:

Platform: NVIDIA CUDA
Device 0: Tesla M2090
Device 1: Tesla M2090

Nvidia cuda_6.0.37 SDK and drivers.
Linux localhost 3.12.0 #6 SMP Thu Apr 17 20:21:10 MSK 2014 x86_64 x86_64 x86_64 GNU/Linux

更新:Nvidia 接受这是一个错误。

更新 1:在我的笔记本电脑(MBP15、AMD GPU、Apple OpenCL)上,程序显示出类似的行为,但在 clFlush 中等待更多(>99%)。在 CUDA SDK 上,该程序在没有 clFlush 的情况下工作,在没有 clFlush 的 Apple 程序上挂起(提交的任务永远不会完成)。

4

1 回答 1

1

我尝试过内存锁定,它显着改善了这种情况!

问题解决了。

我认为这不是一个真正的错误。我只是错过了文档中的一些内容。我的调查使我得出结论,即使使用了非​​阻塞调用,驱动程序也无法执行非固定缓冲区的异步加载/存储。驱动程序只是等待存储/加载数据的机会,这只能在任务完成后执行,这会破坏并行性。

于 2014-07-30T19:48:54.510 回答