While measuring performance of the same kernel on CUDA and OpenCL, I've found one weird thing.
When I leave my kernel absolutely empty, without any input parameters and calculations, CUDA gives me very poor performance, in comparison to OpenCL.
CUDA kernel:
__global__ void kernel_empty()
{
}
CUDA host:
kernel_empty<<<dim3(10000, 10000, 1), dim3(8, 8, 1)>>>();
OpenCl kernel:
__attribute__((reqd_work_group_size(8, 8, 1)))
__kernel void kernel_empty()
{
}
OpenCL host:
cl_event perf_event;
size_t global_work_offset[3] = {0, 0, 0};
size_t global_work_size[3] = {10000, 10000, 1};
size_t local_work_size[3] = {8, 8, 1};
clEnqueueNDRangeKernel(queue, kernel, 3, global_work_offset, global_work_size, local_work_size, 0, NULL, &perf_event);
OpenCL gives 6ms
CUDA gives 390ms
- Kernels on both APIs are working correctly, since I'm using them to calculate my stuff.
- There are no error codes returned on both sides.
- Visual Studio 2010 is used, release mode
- OpenCL 1.1 lib from NVIDIA GPU Computing Toolkit 5.5
- CUDA lib from NVIDIA GPU Computing Toolkit 5.5
- Timings are also correct, I've double checked them with CPU timer. Also when using huge grid, you can see how CUDA lags without any timers.
- For OpenCL
clGetEventProfilingInfois used. - For CUDA
cudaEventElapsedTimeis used.
- For OpenCL
- The tests were running on the same PC with NVIDIA Quadro K4000.
Could someone explain why there is such huge difference?
clEnqueueNDRangeKernel? I've just tried this on some NVIDIA GPUs and I'm getting runtimes in the hundreds of milliseconds, like your CUDA implementation. - jprice