I'm running an OpenCL kernel that processes and re-processes the same data set over and over (it's an iterative physics solver).
In my tests, there is a non-trivial cost to calling clEnqueueNDRangeKernel. For example, when running 1000 substeps of the simulation (requiring 1000 identical calls to clEnqueueNDRangeKernel to process the same data), it seems that those calls to clEnqueueNDRangeKernel actually become the bottleneck. My (pseudo)code looks like this:
[create buffers]
[set kernel arguments]
for (int i = 0; i < 1000; i++) //queuing the kernels takes a while
{
clEnqueueNDRangeKernel(queue, kernel, args...);
}
clFinish(queue); //waiting for the queue to complete doesn't take much time
[read buffers]
I understand that the first call to clEnqeueuNDRangeKernel will initialize any deferred buffer transfers to the GPU...so the first call can have an additional cost. However, in my tests, a loop of 10 iterations is substantially faster than 1000 iterations, which leads me to believe the data transfer is not the bottleneck.
I'm also under the impression that clEnqueueNDRangeKernel is non-blocking in the sense that it won't block until the kernel is complete, so the complexity of the kernel shouldn't be the bottleneck (in my case, the kernel execution shouldn't block until the call to clFinish()).
However, when I profiled my code, the majority of time is spent merely processing the for loop, prior to the call to clFinish()...so it seems that the queuing of the kernels themselves is what's taking the most time here.
My question: is there a way to tell the GPU to re-run a previously-queued kernel N times, rather than having to manually queue a kernel N times? In my situation, no arguments for the kernel need to be changed or updated each iteration...the kernel just needs to be re-run. Can repeated calls to it be made more efficient?
clFlush()every say 100 iterations to trigger kernel processing? - doqtor