2013-04-23 2 views
7

Problema: Segmentation fault (SIGSEGV, segnale 11)Segmentation fault in __pthread_getspecific chiamato da libcuda.so.1

Breve descrizione programma:

  • alte prestazioni GPU (CUDA) gestione del server richieste da remoto clienti
  • ogni richiesta in ingresso genera un thread che esegue calcoli su più GPU (seriale, non in parallelo) e invia restituisce un risultato al client, solitamente richiede da 10 a 200ms poiché ogni richiesta è composta da decine o centinaia di chiamate al kernel
  • I thread del gestore delle richieste hanno accesso esclusivo alle GPU, il che significa che se un thread esegue qualcosa su GPU1 gli altri dovranno aspettare fino a quando il suo fare
  • compilato con -arch = sm_35 -code = compute_35
  • usando CUDA 5.0
  • non sto utilizzando qualsiasi Atomics CUDA esplicitamente o qualsiasi barriera di sincronizzazione in-kernel, anche se i' m usando thrust (varie funzioni) e cudaDeviceSynchronize() ovviamente
  • Driver Nvidia: NVIDIA dlloader X driver 313.30 mer 27 mar 15:33:21 PDT 2013

OS e informazioni HW:

  • Linux lub1 3.5.0-23-generiC# 35 ~ precise1-Ubuntu x86_64 x86_64 x86_64 GNU/Linux
  • GPU: 4x GPU 0: GeForce GTX TITAN
  • 32 GB di RAM
  • MB: Asus Maximus V EXTREME
  • CPU: i7-3770K

Crash informazioni:

arresto anomalo del sistema "a caso" dopo un paio di migliaia di richieste sono gestite (a volte presto, a volte più tardi). stack da alcuni dei crash simile a questa:

#0 0x00007f8a5b18fd91 in __pthread_getspecific (key=4) at pthread_getspecific.c:62 
#1 0x00007f8a5a0c0cf3 in ??() from /usr/lib/libcuda.so.1 
#2 0x00007f8a59ff7b30 in ??() from /usr/lib/libcuda.so.1 
#3 0x00007f8a59fcc34a in ??() from /usr/lib/libcuda.so.1 
#4 0x00007f8a5ab253e7 in ??() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#5 0x00007f8a5ab484fa in cudaGetDevice() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#6 0x000000000046c2a6 in thrust::detail::backend::cuda::arch::device_properties()() 


#0 0x00007ff03ba35d91 in __pthread_getspecific (key=4) at pthread_getspecific.c:62 
#1 0x00007ff03a966cf3 in ??() from /usr/lib/libcuda.so.1 
#2 0x00007ff03aa24f8b in ??() from /usr/lib/libcuda.so.1 
#3 0x00007ff03b3e411c in ??() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#4 0x00007ff03b3dd4b3 in ??() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#5 0x00007ff03b3d18e0 in ??() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#6 0x00007ff03b3fc4d9 in cudaMemset() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#7 0x0000000000448177 in libgbase::cudaGenericDatabase::cudaCountIndividual(unsigned int, ... 


#0 0x00007f01db6d6153 in ??() from /usr/lib/libcuda.so.1 
#1 0x00007f01db6db7e4 in ??() from /usr/lib/libcuda.so.1 
#2 0x00007f01db6dbc30 in ??() from /usr/lib/libcuda.so.1 
#3 0x00007f01db6dbec2 in ??() from /usr/lib/libcuda.so.1 
#4 0x00007f01db6c6c58 in ??() from /usr/lib/libcuda.so.1 
#5 0x00007f01db6c7b49 in ??() from /usr/lib/libcuda.so.1 
#6 0x00007f01db6bdc22 in ??() from /usr/lib/libcuda.so.1 
#7 0x00007f01db5f0df7 in ??() from /usr/lib/libcuda.so.1 
#8 0x00007f01db5f4e0d in ??() from /usr/lib/libcuda.so.1 
#9 0x00007f01db5dbcea in ??() from /usr/lib/libcuda.so.1 
#10 0x00007f01dc11e0aa in ??() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#11 0x00007f01dc1466dd in cudaMemcpy() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#12 0x0000000000472373 in thrust::detail::backend::cuda::detail::b40c_thrust::BaseRadixSortingEnactor 


#0 0x00007f397533dd91 in __pthread_getspecific (key=4) at pthread_getspecific.c:62 
#1 0x00007f397426ecf3 in ??() from /usr/lib/libcuda.so.1 
#2 0x00007f397427baec in ??() from /usr/lib/libcuda.so.1 
#3 0x00007f39741a9840 in ??() from /usr/lib/libcuda.so.1 
#4 0x00007f39741add08 in ??() from /usr/lib/libcuda.so.1 
#5 0x00007f3974194cea in ??() from /usr/lib/libcuda.so.1 
#6 0x00007f3974cd70aa in ??() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#7 0x00007f3974cff6dd in cudaMemcpy() from /usr/local/cuda-5.0/lib64/libcudart.so.5.0 
#8 0x000000000046bf26 in thrust::detail::backend::cuda::detail::checked_cudaMemcpy(void* 

Come si può vedere, di solito finisce in __pthread_getspecific chiamato da libcuda.so o da qualche parte nella biblioteca stessa. Per quanto ricordo, c'è stato un solo caso in cui non si è bloccato ma invece è stato impiccato in un modo strano: il programma è stato in grado di rispondere alle mie richieste se non comportavano alcun calcolo della GPU (statistiche ecc.), Ma altrimenti non ho mai avuto una risposta Inoltre, facendo nvidia-smi -L non ha funzionato, è rimasto bloccato fino a quando non ho riavviato il computer. Mi sembrava una sorta di deadlock della GPU. Questo potrebbe essere un problema completamente diverso da questo però.

Qualcuno ha la minima idea di dove potrebbe essere il problema o che cosa potrebbe causare questo?

Aggiornamenti:

alcune analisi supplementari:

  • cuda-memcheck non stampa eventuali messaggi di errore.
  • valgrind - controllo delle perdite fa stampare un bel paio di messaggi, come quelli di seguito (ci sono centinaia genere):
==2464== 16 bytes in 1 blocks are definitely lost in loss record 6 of 725 
==2464== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2464== by 0x568C202: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 
==2464== by 0x56B859D: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 
==2464== by 0x5050C82: __nptl_deallocate_tsd (pthread_create.c:156) 
==2464== by 0x5050EA7: start_thread (pthread_create.c:315) 
==2464== by 0x6DDBCBC: clone (clone.S:112) 
==2464== 
==2464== 16 bytes in 1 blocks are definitely lost in loss record 7 of 725 
==2464== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2464== by 0x568C202: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 
==2464== by 0x56B86D8: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 
==2464== by 0x5677E0F: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 
==2464== by 0x400F90D: _dl_fini (dl-fini.c:254) 
==2464== by 0x6D23900: __run_exit_handlers (exit.c:78) 
==2464== by 0x6D23984: exit (exit.c:100) 
==2464== by 0x6D09773: (below main) (libc-start.c:258) 

==2464== 408 bytes in 3 blocks are possibly lost in loss record 222 of 725 
==2464== at 0x4C29DB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2464== by 0x5A89B98: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5A8A1F2: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5A8A3FF: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5B02E34: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5AFFAA5: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5AAF009: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5A7A6D3: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x59B205C: ??? (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x5984544: cuInit (in /usr/lib/libcuda.so.313.30) 
==2464== by 0x568983B: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 
==2464== by 0x5689967: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) 

Maggiori informazioni:

ho provato a funzionare con meno carte (3, poiché questo è il minimo necessario per il programma) e il crash si verifica ancora.

Quanto sopra non è vero, i mal configurati l'applicazione e usato tutti quattro carte. Rieseguire gli esperimenti con solo 3 schede sembra risolvere il problema, ora è in esecuzione per diverse ore sotto carico pesante senza arresti anomali. Ora cercherò di lasciarlo correre un po 'di più e magari tentare di usare un sottoinsieme diverso di 3 carte per verificarlo e allo stesso tempo testare se il problema è legato a una particolare carta o meno.

Ho monitorato la temperatura della GPU durante i test e non sembra esserci nulla di sbagliato. Le carte arrivano a circa 78-80 ° C con il carico più alto con la ventola che va a circa il 56% e questo rimane fino a quando non si verifica l'incidente (alcuni minuti), non sembra essere troppo alto per me.

Una cosa che ho pensato è il modo in cui le richieste vengono gestite - c'è un bel po 'di cudaSetDevice chiama, dal momento che ogni richiesta genera un nuovo thread (sto usando biblioteca mangusta) e poi questa discussione passa tra le schede chiamando cudaSetDevice (id) con id del dispositivo appropriato. La commutazione può avvenire più volte durante una richiesta e non sto utilizzando alcun flusso (quindi tutto va al flusso di dati predefinito (0) IIRC). Questo può essere in qualche modo correlato agli arresti anomali che si verificano in pthread_getspecific?

Ho anche provato l'aggiornamento ai driver più recenti (beta, 319.12) ma ciò non ha aiutato.

+0

Questo potrebbe essere un bug nei driver, CUDA o entrambi. Se questo è il caso, tutto ciò che puoi fare è provare a fare un codice di riproduzione, inviarlo alla piattaforma di bug report di NVIDIA e aspettare una risposta. Ti diranno che devi aspettare la prossima versione di CUDA (5.5), e nel frattempo potresti essere fortunato con i prossimi driver. L'ultimo bug che ho segnalato è svanito con gli attuali driver beta (319.12), ma ho ricevuto due bug aggiuntivi, quindi ... Comunque, penso che potresti essere più fortunato se lo pubblichi sui forum NVIDIA. – BenC

+0

@ BenC: grazie, proverò a postare anche lì. – PeterK

+0

Questo potrebbe anche essere qualcos'altro, ma gli sviluppatori NVIDIA dovrebbero essere in grado di fornire alcune informazioni che gli utenti di Stack Overflow non hanno. – BenC

risposta

5

Se è possibile identificare 3 carte che funzionano, provare a pedalare la 4a carta al posto di una delle 3, e vedere se si ottengono nuovamente i guasti. Questa è solo la risoluzione dei problemi standard, credo. Se riesci a identificare una singola carta che, quando è inclusa in un gruppo di 3, suscita ancora il problema, allora quella carta è sospetta.

Tuttavia, il mio suggerimento di eseguire con meno schede era basato anche sull'idea che potesse ridurre il carico generale sull'unità di alimentazione. Anche a 1500W, potresti non avere abbastanza succo. Quindi se fai girare la quarta carta al posto di una delle 3 (cioè mantieni solo 3 carte nel sistema o configura la tua app per usarne 3) e non ottieni fallimenti, il problema potrebbe essere dovuto alla potenza generale assorbita con 4 carte

Si noti che il consumo energetico di GTX Titan a pieno carico può essere dell'ordine di 250 W o forse di più. Quindi potrebbe sembrare che il tuo alimentatore da 1500 W dovrebbe andare bene, ma potrebbe essere necessario analizzare attentamente la quantità di corrente continua disponibile su ogni binario, e come la scheda madre e l'alimentatore PSU stiano distribuendo le rotaie da 12 V CC a ciascuna GPU.

Quindi, se la riduzione a 3GPU sembra risolvere il problema indipendentemente dal numero 3 che si utilizza, suppongo che il PSU non sia all'altezza del compito. Non tutti i 1500W sono disponibili da una singola guida DC. Il "binario" 12V è in realtà composto da diverse rotaie da 12 V, ciascuna delle quali eroga una certa porzione del totale di 1500 W. Quindi, anche se potresti non tirare 1500W, puoi ancora sovraccaricare un singolo binario, a seconda di come l'alimentazione della GPU è collegata alle rotaie.

Sono d'accordo sul fatto che le temperature nell'intervallo 80C dovrebbero andare bene, ma ciò indica (approssimativamente) una GPU completamente carica, quindi se lo vedete su tutte e 4 le GPU contemporaneamente, state caricando un carico pesante.

+0

@PeterK: Se il primo test di Robert non mostra alcun malfunzionamento hardware per una delle schede, potrebbe essere saggio eseguire un altro test di stress sul sistema. Se il problema è il consumo di energia, uno stress stress molto impegnativo dovrebbe teoricamente portare allo stesso problema. Non so se ci sia uno strumento perfetto per questo (qualcosa come [questo programma] (http://wili.cc/blog/gpu-burn.html) o [quello] (http://sourceforge.net/ progetti/cudagpumemtest /), forse?). Se riscontri gli stessi problemi con lo stress test, sapresti che il tuo programma non è difettoso. – BenC

+0

Grazie per l'aiuto. Mentre non so ancora quale sia la causa del problema, sono ora in contatto con gli ingegneri di NVIDIA, quindi speriamo che lo scopriremo. – PeterK