Tengo algo muy similar al código:CUDA no corrientes de la superposición
int k, no_streams = 4;
cudaStream_t stream[no_streams];
for(k = 0; k < no_streams; k++) cudaStreamCreate(&stream[k]);
cudaMalloc(&g_in, size1*no_streams);
cudaMalloc(&g_out, size2*no_streams);
for (k = 0; k < no_streams; k++)
cudaMemcpyAsync(g_in+k*size1/sizeof(float), h_ptr_in[k], size1, cudaMemcpyHostToDevice, stream[k]);
for (k = 0; k < no_streams; k++)
mykernel<<<dimGrid, dimBlock, 0, stream[k]>>>(g_in+k*size1/sizeof(float), g_out+k*size2/sizeof(float));
for (k = 0; k < no_streams; k++)
cudaMemcpyAsync(h_ptr_out[k], g_out+k*size2/sizeof(float), size2, cudaMemcpyDeviceToHost, stream[k]);
cudaThreadSynchronize();
cudaFree(g_in);
cudaFree(g_out);
'h_ptr_in' y 'h_ptr_out' son matrices de punteros asignados con cudaMallocHost (sin banderas).
El problema es que las transmisiones no se superponen. En el generador de perfiles visual, puedo ver la ejecución del núcleo de la primera secuencia superpuesta con la copia (H2D) de la segunda secuencia, pero nada más se solapa.
Puede que no tenga recursos para ejecutar 2 kernels (creo que sí) pero al menos la ejecución y copia del kernel deberían estar superpuestas, ¿no? Y si puse los 3 (copia H2D, ejecución del kernel, copia D2H) dentro del mismo for-loop ninguno de ellos se superponen ...
Por favor AYUDA, ¿qué puede estar causando esto?
estoy corriendo en:
Ubuntu 10.04 x64
dispositivo: "GeForce GTX 460" (CUDA Driver Versión: 3.20, CUDA Runtime Versión: 3.20, CUDA Capacidad versión principal/menor número: 2.1, copia concurrente y ejecución: Sí, concurrente ejecución del kernel: Sí)
El mecanismo de creación de perfiles en CUDA causa la serialización dentro de las transmisiones en algunas circunstancias. No puede usar el generador de perfiles para juzgar la superposición de operaciones API asíncronas. – talonmies
Gracias. ¿Hay alguna otra forma de saber con certeza si la superposición es correcta? A juzgar por los tiempos, no parece ser ... – pmcr
¿Cómo lo estás cronometrando? – talonmies