我的OpenCL program(不要害怕,这是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接受了这个错误。
Update1:在我的笔记本电脑(MBP15,AMD GPU,Apple OpenCL)上,该程序显示出类似的行为,但在clFlush中等待更多(> 99%)。在CUDA SDK上,程序在没有clFlush的情况下工作,在没有clFlush挂起的Apple程序上(提交的任务永远不会完成)。
答案 0 :(得分:1)
我尝试了记忆力,这显着改善了情况!
问题解决了。
我认为这不是一个真正的错误;我刚刚错过了文档中的内容。我的调查得出结论,即使使用非阻塞调用,驱动程序也无法执行非固定缓冲区的异步加载/存储。驱动程序只是等待存储/加载数据的机会,这可以在任务完成后执行,这会破坏并行性。