I’m trying to gauge the overhead associated with a kernel call. Unless i call the kernel a zillion of times in this loop, the launch overhead is actually really bad on my machine (unless i’m overlooking something). I’d like to know if anyone has tried a similar experiment and what its conclusions were.
I’m reporting results obtained on XP, with DevStudio2005, CUDA 1.1. I ran this on a DELL, Xeon, quad core, 2.8GHz, 3Gb RAM.
I used a grid of 1000 by 1000 blocks, each with 256 by 256 threads. In fact, the timing results seem to be insensitive to the execution configuration.
Here is what i got (i list the number of times i run the loop that invokes the empty kernel. I report three sets of results just to be able to get an idea about an average here…)
Loop w/ 1 kernel call
Processing time: 79.262657 (ms)
Processing time: 77.801155 (ms)
Processing time: 77.531998 (ms)
Loop 10 kernel calls
Processing time: 76.896141 (ms)
Processing time: 77.876907 (ms)
Processing time: 77.362549 (ms)
Loop 100 kernel calls
Processing time: 79.482323 (ms)
Processing time: 79.455841 (ms)
Processing time: 80.660873 (ms)
Loop 1000 kernel calls
Processing time: 86.425369 (ms)
Processing time: 85.208755 (ms)
Processing time: 84.457947 (ms)
Loop 10000 kernel calls
Processing time: 152.974518 (ms)
Processing time: 157.944000 (ms)
Processing time: 152.800629 (ms)
Loop 100000 kernel calls
Processing time: 836.776672 (ms)
Processing time: 837.642090 (ms)
Processing time: 827.006958 (ms)
Loop 1000000 kernel calls
Processing time: 7606.758789 (ms)
Processing time: 7628.625977 (ms)
Processing time: 7610.461426 (ms)
Loop 2000000 kernel calls
Processing time: 16004.808594 (ms)
Processing time: 15134.964844 (ms)
Processing time: 15147.358398 (ms)
I used the code below:
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <cutil.h>
__global__ void empty() {}
/************************************************************************/
/* Timing overhead of launching a kernel */
/************************************************************************/
int main(int argc, char* argv[])
{
int num_blocks = atoi(argv[1]);
int num_threads = atoi(argv[2]);
int num_times = atoi(argv[3]);
// setup timer
unsigned int timer = 0;
CUT_SAFE_CALL( cutCreateTimer( &timer));
CUT_SAFE_CALL( cutStartTimer( timer));
// setup execution parameters
dim3 gridStruct (num_blocks, num_blocks, 1);
dim3 blockStruct(num_threads, num_threads, 1);
for(int i = 0; i < num_times; i++)
{
empty<<<gridStruct, blockStruct>>>();
}
CUT_SAFE_CALL( cutStopTimer( timer));
printf("Processing time: %f (ms)\n", cutGetTimerValue( timer));
CUT_SAFE_CALL( cutDeleteTimer( timer));
return 0;
}
btw, i used the following command line:
/OUT:“…....\bin\win32\Release\kernelCallOverhead.exe” /INCREMENTAL:NO /NOLOGO /LIBPATH:“C:\CUDA\lib” /LIBPATH:“C:\Progra~1\NVIDIA~1\NVIDIA~1\common\lib” /MANIFEST /MANIFESTFILE:“Release\kernelCallOverhead.exe.intermediate.manifest” /DEBUG /PDB:“c:\Program Files\NVIDIA Corporation\NVIDIA CUDA SDK\bin\win32\Release\kernelCallOverhead.pdb” /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT cudart.lib cutil32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib