programming - cuda tutorial
Diferencia en la creación de un contexto CUDA (1)
Tengo un programa que usa tres kernels. Para obtener las aceleraciones, estaba haciendo una copia de memoria ficticia para crear un contexto de la siguiente manera:
__global__ void warmStart(int* f)
{
*f = 0;
}
que se lanza antes de los kernels que quiero cronometrar de la siguiente manera:
int *dFlag = NULL;
cudaMalloc( (void**)&dFlag, sizeof(int) );
warmStart<<<1, 1>>>(dFlag);
Check_CUDA_Error("warmStart kernel");
También leí sobre otras formas más simples de crear un contexto como cudaFree(0)
o cudaDevicesynchronize()
. Pero el uso de estas llamadas API da tiempos peores que el uso del kernel ficticio.
Los tiempos de ejecución del programa, después de forzar el contexto, son 0.000031
segundos para el núcleo ficticio y 0.000064
segundos para ambos, cudaDeviceSynchronize () y cudaFree (0). Los tiempos se obtuvieron como una media de 10 ejecuciones individuales del programa.
Por lo tanto, la conclusión a la que he llegado es que el lanzamiento de un kernel inicializa algo que no se inicializa al crear un contexto de forma canónica.
Entonces, ¿cuál es la diferencia de crear un contexto de estas dos maneras, usando un kernel y usando una llamada API?
Ejecuto la prueba en una GTX480, usando CUDA 4.0 bajo Linux.
Cada contexto CUDA tiene asignaciones de memoria que se requieren para ejecutar un kernel que no es necesario asignar para sincronicizar, asignar memoria o memoria libre. La asignación inicial de la memoria de contexto y el cambio de tamaño de estas asignaciones se difiere hasta que un kernel requiera estos recursos. Los ejemplos de estas asignaciones incluyen el buffer de memoria local, el montón de dispositivo y el montón de printf.