Modi per visualizzare i dati degli eventi in cerca di problemi di prestazioni


10

Sto cercando di ottimizzare un'applicazione MPI con un modello di comunicazione altamente asincrono. Ogni rango ha un elenco di cose da calcolare e invia messaggi, se necessario, se gli input o gli output si trovano su un rango diverso. Inoltre, ogni rango è infilato (attualmente con un thread di comunicazione e 5 lavoratori).

Ho strumentato il codice con timer attorno alle diverse porzioni di codice critiche per le prestazioni, che mi dà un elenco di triple (inizio, fine, tipo) per ogni thread. Tracciato in modo ovvio, con il tempo come asse orizzontale, rango e filo come verticale e colore che indica cosa sta facendo ogni filo, ottengo un'immagine come questa per 16 ranghi con 6 fili / rango:

Rango di Pentago e cronologia dei thread

La mia domanda è: quali sono altri modi di visualizzare questi dati che potrebbero aiutare a individuare i problemi di prestazioni? Qualcuno ha un tipo preferito di trama che usano quando si profilano le applicazioni asincrone?

Questo set di dati è limitato in quanto non conosce la struttura del flusso di dati, ma mi piacerebbe approfondirne il più possibile prima di provare a raccogliere qualcosa di più complicato.

L'immagine non compressa è qui nel caso in cui qualcuno volesse guardarsi intorno (non è riuscito a caricare attraverso il percorso normale). Sfortunatamente, Firefox non lo accetta anche se credo che sia valido, forse perché è semplicemente troppo grande.


Ho avuto un bel po 'di problemi a caricare il mio browser o quasi qualsiasi altro programma per caricare l'immagine di grandi dimensioni. Alla fine, Gimp lo ha fatto, ma potresti voler riconsiderare le opzioni relative alle dimensioni o al formato del file.
Pedro,

Mi dispiace per quello. Penso che l'immagine sia valida, dal momento che Firefox mi dà gli stessi errori che lo eseguono tramite convert (ImageMagick). Forse supera qualche soglia di dimensione arbitraria.
Geoffrey Irving,

Risposte:


4

Trascorro molto tempo a scrivere e eseguire il debug di codice parallelo, sia con memoria condivisa che distribuita, ma senza conoscere il tuo problema specifico, posso solo dirti cosa funziona meglio per me.

Sapere quali routine impiegano quanto tempo è una cosa importante se si considera l'efficienza computazionale, ma se si è preoccupati dell'efficienza parallela, allora si dovrebbe essere più preoccupati di ciò che il codice sta facendo quando non esegue alcun calcolo. Un po 'come preoccuparsi di quello che fanno i bambini quando è troppo tranquillo ...

Dato che stai usando un approccio ibrido a memoria condivisa / distribuita, immagino che il tuo codice sia, negli spazi vuoti, in attesa di una chiamata MPI o di una variabile mutex / condition. Puoi avvolgere anche queste chiamate nei timer, e questo ti darà un quadro migliore di ciò che ti sta rallentando, ad esempio se è sempre lo stesso condizionale o sempre lo stesso su MPI_REDUCEcui rimangono bloccati i tuoi thread.

Un software che uso abbastanza spesso è Intel Vtune Amplifier XE . Ha una bella caratteristica / opzione per il grafico che visualizza la concorrenza dei thread. Il programma disegnerà una trama molto simile alla tua, ma quando un thread attende un mutex o una variabile condition, disegna una linea diagonale dal thread in attesa, nel momento in cui ha iniziato ad aspettare, al thread che ha effettivamente rilasciato il mutex o segnalato la condizione che stava aspettando, nel momento in cui è stata rilasciata / segnalata. Questo può essere piuttosto disordinato, ma fa apparire immediatamente i colli di bottiglia.

Infine, raccolgo anche statistiche di massa, ad esempio per ogni chiamata mutex / segnale / MPI, quali sono stati i tempi di attesa medi e massimi? Qual è l'istogramma dei tempi di attesa raccolti? Mentre la trama ti dà una bella panoramica, può diventare piuttosto confusa quando si tratta dei dettagli.

Infine, una domanda da non sottovalutare: come raccogli i tuoi tempi? Il tuo timer non è abbastanza invadente per non influenzare il tuo codice? Uso il conteggio delle istruzioni della CPU ogni volta che è possibile, ovvero RDTSCsu architetture x86. Questo di solito aggiunge solo una singola istruzione al tuo codice.


I dati hanno già dei blocchi attorno a tutte le attese; nel diagramma vengono visualizzati in bianco per i thread di lavoro inattivi e in giallo per i thread di comunicazione in attesa. Sfortunatamente, tutte le attese nel thread di comunicazione si verificano in una singola coperta MPI_Waitsome a causa dell'asincronia. Vtune non si applica in questo caso poiché le prestazioni puramente thread sono essenzialmente perfette, ma grazie per il puntatore. Anche il suggerimento dell'istogramma è buono.
Geoffrey Irving,

Per quanto riguarda i tempi di overhead: sto usando gettimeofday, che è necessario almeno attorno alle sezioni inattive poiché lì uso variabili di condizione pthread. Il conteggio delle istruzioni della CPU può funzionare in una situazione del genere? Il sovraccarico è già abbastanza basso, ma inferiore sarebbe sicuramente più bello.
Geoffrey Irving,

1
@GeoffreyIrving: Sì, puoi usarli, ma hanno senso solo su CPU che hanno il constant_tscflag impostato (check /proc/cpuinfo) e se usi lock ogni thread su un core specifico, cioè ogni thread legge sempre lo stesso registro dallo stesso core, ad es pthread_setaffinity_np. usando . Si noti che quest'ultimo è specifico di Linux e quindi non portatile.
Pedro,

@GeoffreyIrving: anche se stai aspettando un evento non divulgato utilizzando MPI_Waitsome, puoi comunque registrare quali richieste sono effettivamente arrivate e da dove. Queste informazioni potrebbero essere o non essere utili ...
Pedro

5

A volte è possibile ottenere una visione alternativa sui problemi di prestazioni tramite un'analisi delle risorse di alto livello: esiste un collo di bottiglia rilevante come la larghezza di banda della memoria? Ogni thread di lavoro fa lo stesso lavoro? Questi dati potrebbero essere raccolti facilmente con likwid-perfctr dal progetto di codice Google LIKWID della suite di strumenti LIKWID . Se il profilo è tale che esistono molti punti caldi diversi, potrebbe essere necessario affrontarli uno per uno. Potrebbero inoltre esserci problemi diversi, a seconda del numero di thread / processi utilizzati.


Nell'interesse di una perfetta divulgazione, Georg lavora al progetto LIKWID e ho sollecitato questa risposta perché volevo integrare la grande risposta di Pedro con un'altra prospettiva (e un ottimo strumento liberamente disponibile).
Aron Ahmadia,

2

Quando ho un problema in una rete di processi altamente asincroni governati da messaggi o eventi, utilizzo un metodo non facile ma efficace. Si trattava di ottenere registri dei processi timestamp, unirli in una sequenza temporale comune e tenere traccia dell'avanzamento di alcuni messaggi mentre attivano le attività, attivando ulteriori messaggi. Quello che sto cercando è il ritardo tra il momento in cui un messaggio viene ricevuto e il momento in cui viene recepito, e la comprensione del motivo del ritardo. Quando viene rilevato un problema, viene risolto e il processo viene ripetuto. In questo modo, puoi ottenere prestazioni davvero soddisfacenti.

È importante vedere come questo differisce dagli approcci in cui si misura, misura, misura. L'unica cosa che la misurazione può concepibilmente dirti è dove non guardare. L'ottimizzazione delle prestazioni reali richiede un'attenta analisi dei dettagli, dal punto di vista temporale. Quello che stai cercando non è dove il tempo è trascorso, ma dove è trascorso inutilmente.

In bocca al lupo.


In altre parole, non esiste una visualizzazione utile dei dati che ho. :) Jed Brown ha suggerito Jumpshot (e le utilità associate) come un modo per raccogliere e visualizzare i dati che suggerisci, quindi lo esaminerò.
Geoffrey Irving,

@Geof: buona fortuna con la visualizzazione. L'unico strumento che avrei trovato utile è qualcosa per raccogliere e unire i log degli eventi in modo da poter seguire il percorso di una o più richieste mentre si faceva strada attraverso i vari thread, perché è l'unico modo che conosco per rilevare inutili ritardi. Ecco in cosa consisterà qualsiasi problema di prestazioni: ritardi non necessari.
Mike Dunlavey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.