Estoy tratando de perfilar mi red pytorch para ver cuál es el cuello de botella. Noté que hay una operación llamada cudaLaunchKernel que ocupa la mayor parte del tiempo. Esta respuesta dice que se llama para cada operación realizada con cuda. Si supongamos que implemento esta red en C++ o cualquier otro lenguaje, ¿sería posible reducir este tiempo?
Básicamente, estoy preguntando si esta sobrecarga se debe a que implementé mi red en python o esta sobrecarga estará siempre ahí y será imposible de optimizar en cualquier idioma.
Salida completa del generador de perfiles:
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls ------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ cudaLaunchKernel 99.80% 933.739ms 99.80% 933.739ms 20.750ms 0.000us 0.00% 0.000us 0.000us 45 model_inference 0.05% 453.000us 100.00% 935.567ms 935.567ms 0.000us 0.00% 195.000us 195.000us 1 aten::cudnn_convolution 0.04% 388.000us 99.84% 934.047ms 103.783ms 195.000us 100.00% 195.000us 21.667us 9 aten::_convolution 0.01% 138.000us 99.88% 934.419ms 103.824ms 0.000us 0.00% 195.000us 21.667us 9 aten::conv2d 0.01% 122.000us 99.89% 934.592ms 103.844ms 0.000us 0.00% 195.000us 21.667us 9 aten::add_ 0.01% 112.000us 0.02% 155.000us 17.222us 0.000us 0.00% 0.000us 0.000us 9 aten::upsample_nearest2d 0.01% 82.000us 0.01% 105.000us 26.250us 0.000us 0.00% 0.000us 0.000us 4 aten::empty 0.01% 79.000us 0.01% 79.000us 3.292us 0.000us 0.00% 0.000us 0.000us 24 aten::threshold 0.01% 74.000us 0.02% 149.000us 18.625us 0.000us 0.00% 0.000us 0.000us 8 aten::_cat 0.01% 71.000us 0.01% 119.000us 29.750us 0.000us 0.00% 0.000us 0.000us 4 aten::relu 0.01% 57.000us 0.02% 206.000us 25.750us 0.000us 0.00% 0.000us 0.000us 8 aten::convolution 0.01% 51.000us 99.88% 934.470ms 103.830ms 0.000us 0.00% 195.000us 21.667us 9 aten::view 0.01% 50.000us 0.01% 50.000us 5.556us 0.000us 0.00% 0.000us 0.000us 9 aten::cat 0.00% 32.000us 0.02% 151.000us 37.750us 0.000us 0.00% 0.000us 0.000us 4 aten::reshape 0.00% 29.000us 0.01% 79.000us 8.778us 0.000us 0.00% 0.000us 0.000us 9 aten::resize_ 0.00% 25.000us 0.00% 25.000us 0.962us 0.000us 0.00% 0.000us 0.000us 26 aten::rsub 0.00% 21.000us 0.00% 33.000us 33.000us 0.000us 0.00% 0.000us 0.000us 1 aten::mul 0.00% 17.000us 0.00% 27.000us 27.000us 0.000us 0.00% 0.000us 0.000us 1 aten::zeros 0.00% 13.000us 0.00% 16.000us 16.000us 0.000us 0.00% 0.000us 0.000us 1 cudaEventRecord 0.00% 12.000us 0.00% 12.000us 1.333us 0.000us 0.00% 0.000us 0.000us 9 cudaBindTexture 0.00% 11.000us 0.00% 11.000us 2.750us 0.000us 0.00% 0.000us 0.000us 4 aten::empty_strided 0.00% 6.000us 0.00% 6.000us 6.000us 0.000us 0.00% 0.000us 0.000us 1 aten::zero_ 0.00% 1.000us 0.00% 1.000us 1.000us 0.000us 0.00% 0.000us 0.000us 1 cudnn::maxwell::gemm::computeOffsetsKernel(cudnn::ma... 0.00% 0.000us 0.00% 0.000us 0.000us 195.000us 100.00% 195.000us 195.000us 1 cudaUnbindTexture 0.00% 0.000us 0.00% 0.000us 0.000us 0.000us 0.00% 0.000us 0.000us 4 ------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ Self CPU time total: 935.583ms Self CUDA time total: 195.000us PD: Algunas configuraciones
Versión de Python: 3.8.8
Versión de PyTorch: 1.8.1
versión de cudatoolkit: 10.2.89
versión cuda (según lo dado por nvidia-smi): 11.4
Especificaciones de la CPU: Intel Core i7 10700 a 2,90 GHz 16 núcleos Especificaciones de la GPU: NVIDIA GM204GL [Quadro M4000] RAM: 64 GB GPU RAM: 8 GB SO: Ubuntu 20.04.3 de 64 bits
PPS: no estoy buscando formas de acelerar mi código. Quiero saber si es posible acelerarlo codificándolo en otro idioma como cpp o directamente en cuda. (Supongamos que si todos mis datos ya están en la GPU y he escrito mi código en el lenguaje cuda, ¿funcionaría en 195us ?)
De acuerdo con los documentos de CUDA, se llama a cudaLaunchKernel para iniciar una función de dispositivo , que, en resumen, es un código que se ejecuta en un dispositivo GPU.
El generador de perfiles, por lo tanto, afirma que una gran cantidad de cómputo se ejecuta en la GPU (como probablemente esperaba) y esto requiere que las estructuras de datos se transfieran al dispositivo. Esta puede ser la fuente del cuello de botella.
Normalmente no desarrollo en CUDA, pero tal vez pueda acelerar el proceso codificando kernels más grandes con más operaciones en CUDA y menos transferencias de CPU/GPU.
Echa un vistazo a este tutorial para más detalles.