2012-02-12 10 views
7

Ho un programma che si adatta in modo anomalo a più thread, sebbene - in teoria - debba scalare linearmente: è un calcolo che si divide in blocchi più piccoli e non ha bisogno di chiamate di sistema, chiamate di libreria, blocco, ecc. Il funzionamento con quattro thread è solo circa il doppio della velocità con un singolo thread (su un sistema quad core), mentre mi aspetto un numero più vicino a quattro volte più veloce.Prestazioni e profilatura multi-thread

Il tempo di esecuzione delle implementazioni con pthreads, thread C++ 0x e OpenMP sono d'accordo.

Per individuare la causa, ho provato gprof (inutile) e valgrind (non ho visto nulla di ovvio). Come posso valutare efficacemente cosa sta causando il rallentamento? Qualche idea generica sulle sue possibili cause?

- Aggiornamento -

Il calcolo comporta l'integrazione Monte Carlo e ho notato che una quantità ragionevole di tempo è trascorso generazione di numeri casuali. Mentre non so ancora perché questo accade con quattro thread, ho notato che il generatore di numeri casuali non è rientrante. Quando si usano i mutex, il tempo di esecuzione esplode. Reimplementerò questa parte prima di verificare altri problemi.

Ho reimplementato le classi di campionamento che hanno migliorato notevolmente le prestazioni. Il problema rimanente era, infatti, la contesa delle cache della CPU (è stato rivelato da cachegrind come sospettato da Evgeny).

risposta

4

È possibile utilizzare oprofile. Oppure lo pseudo-profiler di un povero uomo: avvia il programma sotto gdb, fermalo e guarda dove viene fermato. "valgrind --tool = cachegrind" ti mostrerà l'efficienza con cui viene utilizzata la cache della CPU.

L'integrazione di Monte Carlo sembra essere un algoritmo che richiede molta memoria. Prova a stimare come viene utilizzata la larghezza di banda della memoria. Potrebbe essere il fattore limitante per le prestazioni del tuo programma. Inoltre, se il tuo sistema è solo 2-core con hyperthreading, non dovrebbe funzionare molto più velocemente con 4 thread, confrontando con 2 thread.