memory-leaks - how - use valgrind to find memory leaks
Valgrind y CUDA: ¿se reportan fugas reales? (4)
Tengo un componente CUDA muy simple en mi aplicación. Valgrind informa una gran cantidad de fugas y aún inalcanzables, todas relacionadas con las llamadas a cudaMalloc.
¿Estas filtraciones son reales? Llamo a cudaFree
para cada cudaMalloc
. ¿Es la incapacidad de este valrículor para interpretar la asignación de memoria de la GPU? Si estas filtraciones no son reales, ¿puedo suprimirlas y valgrind solo analizar la parte no-gpu de la aplicación?
extern "C"
unsigned int *gethash(int nodec, char *h_nodev, int len) {
unsigned int *h_out = (unsigned int *)malloc(sizeof(unsigned int) * nodec);
char *d_in;
unsigned int *d_out;
cudaMalloc((void**) &d_in, sizeof(char) * len * nodec);
cudaMalloc((void**) &d_out, sizeof(unsigned int) * nodec);
cudaMemcpy(d_in, h_nodev, sizeof(char) * len * nodec, cudaMemcpyHostToDevice);
int blocks = 1 + nodec / 512;
cube<<<blocks, 512>>>(d_out, d_in, nodec, len);
cudaMemcpy(h_out, d_out, sizeof(unsigned int) * nodec, cudaMemcpyDeviceToHost);
cudaFree(d_in);
cudaFree(d_out);
return h_out;
}
El último bit de la salida de Valgrind:
...
==5727== 5,468 (5,020 direct, 448 indirect) bytes in 1 blocks are definitely lost in loss record 506 of 523
==5727== at 0x402B965: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5727== by 0x4843910: ??? (in /usr/lib/nvidia-319-updates/libcuda.so.319.60)
==5727== by 0x48403E9: ??? (in /usr/lib/nvidia-319-updates/libcuda.so.319.60)
==5727== by 0x498B32D: ??? (in /usr/lib/nvidia-319-updates/libcuda.so.319.60)
==5727== by 0x494A6E4: ??? (in /usr/lib/nvidia-319-updates/libcuda.so.319.60)
==5727== by 0x4849534: ??? (in /usr/lib/nvidia-319-updates/libcuda.so.319.60)
==5727== by 0x48191DD: cuInit (in /usr/lib/nvidia-319-updates/libcuda.so.319.60)
==5727== by 0x406B4D6: ??? (in /usr/lib/i386-linux-gnu/libcudart.so.5.0.35)
==5727== by 0x406B61F: ??? (in /usr/lib/i386-linux-gnu/libcudart.so.5.0.35)
==5727== by 0x408695D: cudaMalloc (in /usr/lib/i386-linux-gnu/libcudart.so.5.0.35)
==5727== by 0x804A006: gethash (hashkernel.cu:36)
==5727== by 0x804905F: chkisomorphs (bdd.c:326)
==5727==
==5727== LEAK SUMMARY:
==5727== definitely lost: 10,240 bytes in 6 blocks
==5727== indirectly lost: 1,505 bytes in 54 blocks
==5727== possibly lost: 7,972 bytes in 104 blocks
==5727== still reachable: 626,997 bytes in 1,201 blocks
==5727== suppressed: 0 bytes in 0 blocks
Es un problema conocido que valgrind informa falsos positivos para un montón de cosas de CUDA. La mejor manera de evitar verlo sería usar supresiones valgrind, que puede leer aquí: http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress
Si quiere comenzar algo más cerca de su problema específico, una publicación interesante es esta en los foros de desarrollo de Nvidia. Tiene un enlace a un archivo de regla de supresión de muestra. https://devtalk.nvidia.com/default/topic/404607/valgrind-3-4-suppressions-a-little-howto/
Intenta usar cuda-memcheck --leak-check full
. Cuda-memcheck es un conjunto de herramientas que proporciona una funcionalidad similar a Valgrind para aplicaciones CUDA. Se instala como parte del conjunto de herramientas de CUDA. Puede obtener más documentación sobre cómo usar cuda-memcheck
aquí: http://docs.nvidia.com/cuda/cuda-memcheck/
No confiaría en valgrind ni en ningún otro detector de fugas (como VLD) con CUDA. Estoy seguro de que no fueron diseñados con asignaciones de GPU en mente. No sé si Nvidia Nsight tiene la capacidad en estos días (no he hecho programación de GPU desde hace casi 6 meses), pero eso es lo mejor que utilicé para la depuración de CUDA, y para ser honesto, fue con errores como el infierno .
El código que has publicado no debe crear una fuga.
Para agregar a la respuesta de scarl3tt, esto puede ser demasiado general para algunas aplicaciones, pero si desea usar valgrind mientras ignora la mayoría de los problemas de cuda, use la opción --suppressions = valgrind-cuda.supp donde valgrind-cuda.supp es una archivo con las siguientes reglas:
{
alloc_libcuda
Memcheck:Leak
match-leak-kinds: reachable,possible
fun:*alloc
...
obj:*libcuda.so*
...
}
{
alloc_libcufft
Memcheck:Leak
match-leak-kinds: reachable,possible
fun:*alloc
...
obj:*libcufft.so*
...
}
{
alloc_libcudaart
Memcheck:Leak
match-leak-kinds: reachable,possible
fun:*alloc
...
obj:*libcudart.so*
...
}