PDA

View Full Version : [C] Profiling....(Ottimizzazione codice)


fracarro
04-08-2009, 20:09
Salve ragazzi, ho fatto una ricerca nel forum ma non ho trovato informazioni riguardo al profiling dei codici C (o C++). Scrivo quindi questo topic nella speranza che qualcuno possa chiarirmi le idee a riguardo.

L'obiettivo nell'utilizzare un profiler è, ovviamente, quello di individuare i colli di bottiglia nel codice per sapere con esattezza dove intervenire per migliorarne le performance. A tal fine sto utilizzando 3 profiler (valgrind, gprof e quello di netbeans) differenti che purtroppo però non mi danno gli stessi risultati e la cosa è alquanto fastidiosa (perchè non so di chi fidarmi e quindi su quali funzioni intervenire).

1. I Flag: Allora prima domanda. Quali sono i flag in compilazione da utilizzare per utilizzare questi profiler? Il flag -g credo serva per tutti mentre -pg solo per il gprof. Questione ottimizzazione. I flag -Ox vanno utilizzati su un codice su cui effettuare il profiling oppure bisogna utilizzare il -O0 per eliminare le ottimizzazioni? In quest'ultimo caso non verrebbero falsati i risultati del profiler dato che il codice non ottimizzato ovviamente si comporterà diversamente da quello ottimizzato con -O3? In conclusione voi quale profiler usate e qual'è la riga di compilazione che utilizzate?

2. Sun Studio: Data un'istanza prefissata, ho lanciato dal netbeans il codice su di essa e dopo 300 secondi ho ottenuto il risultato. Il profiler del netbeans (sun studio) però mi segnala che 290 secondi del tempo di cpu sono stati spesi dal libcollector.so. Che cavolo è?

3. Valgrind-kcachegrind: Il profiler più performante e comodo mi sembra valgrind (che lancio con il comando: valgrind --tool=callgrind --simulate-cache=yes --dump-line=yes --dump-instr=yes --collect-jumps=yes --trace-jump=yes eseguibile dati_input ) accoppiato al kcachegrind che legge il file di output generato dal valgrind e ne visualizza il risultato. Tuttavia ho letto dalla guida del callgrind ( http://valgrind.org/docs/manual/cl-manual.html#cl-manual.cycles ) di problemi di profiling che vengono causati dai cicli del codice. Qualcuno di voi sa qualcosa a riguardo?

4. Alternative: Conoscete altri profiler free per linux (oltre a oprofile che non ho capito come funziona)?

Unrue
04-08-2009, 21:06
1. I Flag: Allora prima domanda. Quali sono i flag in compilazione da utilizzare per utilizzare questi profiler? Il flag -g credo serva per tutti mentre -pg solo per il gprof. Questione ottimizzazione. I flag -Ox vanno utilizzati su un codice su cui effettuare il profiling oppure bisogna utilizzare il -O0 per eliminare le ottimizzazioni? In quest'ultimo caso non verrebbero falsati i risultati del profiler dato che il codice non ottimizzato ovviamente si comporterà diversamente da quello ottimizzato con -O3? In conclusione voi quale profiler usate e qual'è la riga di compilazione che utilizzate?


Ciao, dunque i flag che hai citato si utilizzano per i debugger, non per i profiler, ovvero quando cerchi eventuali problemi nel codice. In quel caso devi togliere le ottimizzazioni in quanto le ottimizzazioni cambiano l'assembler sotto e quindi il debugger non ci capisce più nulla.

Quando fai profilazione, ti consiglio -O3 ed i flags per l'analisi interprocedurale, che variano da compilatore a compilatore.(guarda nei manuale). Poi altri flags dipendono da che compilatore hai, dal fatto se vuoi perdere un pò in precisione, dal processore, ecc ecc. Quindi va analizzato caso per caso.

Se hai Intel, questi sono quelli che utliizzo sempre, (puoi cercare gli analoghi nel manuale dei tuo compilatore):

-O3 -ftz -ip -ipo -xW

L'ultimo dipende dal processore in questione( in questo caso Opteron)

fracarro
05-08-2009, 11:35
Ciao, dunque i flag che hai citato si utilizzano per i debugger, non per i profiler, ovvero quando cerchi eventuali problemi nel codice. In quel caso devi togliere le ottimizzazioni in quanto le ottimizzazioni cambiano l'assembler sotto e quindi il debugger non ci capisce più nulla.

Quando fai profilazione, ti consiglio -O3 ed i flags per l'analisi interprocedurale, che variano da compilatore a compilatore.(guarda nei manuale). Poi altri flags dipendono da che compilatore hai, dal fatto se vuoi perdere un pò in precisione, dal processore, ecc ecc. Quindi va analizzato caso per caso.

Se hai Intel, questi sono quelli che utliizzo sempre, (puoi cercare gli analoghi nel manuale dei tuo compilatore):

-O3 -ftz -ip -ipo -xW

L'ultimo dipende dal processore in questione( in questo caso Opteron)

Per quanto riguarda il compilatore , lavoro sotto linux utilizzando il gcc 4.3.3 e vorrei essere il meno possibile dipendente dall'architettura dato che il codice girerà su intel e amd con architetture a 32 e 64 bit.

Per quanto riguarda il flag -g ho seguito le istruzioni indicate qui almeno per quanto riguarda il gprof:
http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html#SEC2
http://www.stanford.edu/class/cme212/profiling.pdf

Per quanto riguarda invece il valgrind, le info sul sito ( http://valgrind.org/docs/manual/cg-manual.html) riguardo il -g riportano questa frase (Paragrafo 5.1.1):
First off, as for normal Valgrind use, you probably want to compile with debugging info (the -g flag). But by contrast with normal Valgrind use, you probably do want to turn optimisation on, since you should profile your program as it will be normally run. :what:

Che significa? Ci vuole o no questo benedetto flag per i simboli del debug?

Ho provato a compilare il codice usando i flag -fipa-pta -fipa-cp per l'analisi interprocedurale (ma non sono sicuro che siano quelli corretti) e il risultatoè stato:
: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.3/README.Bugs> for instructions.:eek:

AnonimoVeneziano
07-08-2009, 00:27
Se fossi in te io userei "-O0" per il profiling, perchè tu devi ottimizzare il tuo codice, non quello prodotto dal compilatore.

Inoltre i veri colli di bottiglia difficilmente vengono risolti dalle ottimizzazioni del compilatore , ma si possono risolvere solo cambiando o migliorando l'algoritmo che si sta usando. (quindi alla fine il risultato finale non è falsato), anzi, i risultati possono sembrarti strani o falsati proprio perchè ottimizzazioni pesanti dei compilatori come "-O3" possono cambiare notevolmente la struttura dell'applicazione a livello di eseguibile, ad esempio eliminando alcune funzioni ed integrandole in altre (inline) o srotolando cicli for ... etc

Può risultare difficile capire dove andare ad intervenire perchè il codice non assomiglia più a quello che hai scritto tu, quindi come primo accorgimento prova a compilare con le ottimizzazioni disabilitate.

Ciao

fracarro
07-08-2009, 07:43
Se fossi in te io userei "-O0" per il profiling, perchè tu devi ottimizzare il tuo codice, non quello prodotto dal compilatore.

Inoltre i veri colli di bottiglia difficilmente vengono risolti dalle ottimizzazioni del compilatore , ma si possono risolvere solo cambiando o migliorando l'algoritmo che si sta usando. (quindi alla fine il risultato finale non è falsato), anzi, i risultati possono sembrarti strani o falsati proprio perchè ottimizzazioni pesanti dei compilatori come "-O3" possono cambiare notevolmente la struttura dell'applicazione a livello di eseguibile, ad esempio eliminando alcune funzioni ed integrandole in altre (inline) o srotolando cicli for ... etc

Può risultare difficile capire dove andare ad intervenire perchè il codice non assomiglia più a quello che hai scritto tu, quindi come primo accorgimento prova a compilare con le ottimizzazioni disabilitate.

Ciao

Quello che dici mi sembra corretto però mi sorge un dubbio a riguardo.

Supponiamo che ci siano due funzioni A e B del mio codice che insieme occupano la maggior parte del tempo di CPU del programma. Ora applicando l'ottimizzazione -O3 magari il compilatore con le sue tecniche mi rende la funzione A molto più efficiente e quindi il profiling con questo flag mi indicherebbe che la funzione da ottimizzare è giustamente la B (dove il compilatore nulla ha potuto). Se invece faccio il profiling con -O0 non essendo avvenuta l'ottimizzazione di A, dovrei cercare di ottimizzare entrambe le funzioni.

In effetti anche quest'ultima ipotesi non è sbagliata, in quanto io devo individuare se possibile tutte le funzioni da ottimizzare, però se il numero di queste funzioni è alto, l'ottimizzazione del compilatore potrebbe restringermi il campo di funzioni su cui è indispensabile intervenire perchè nonostante le ottimizzazioni rimangono i veri colli di bottiglia.

Ad ogni modo proverò anche con il -O0 per vedere i risultati del profiler. Tu che compilatore e profiler usi? Se usi il gcc con quali flag oltre a -O0 compili il sorgente per farne il profiling?

Torav
07-08-2009, 16:29
Io di solito uso i flag -g e -O0 per utilizzare il profiler perché, come dice AnonimoVeneziano, in questa maniera il codice non viene "sporcato" dal compilatore e riesci a trovare i veri colli di bottiglia. Alla fine, quando pensi di aver fatto il massimo puoi dare una controllata anche con -O3, ma francamente non ho mai migliorato un granché (anche considerando che spesso i colli di bottiglia sono in funzioni inline e quindi diventa un casino, con O3, riuscire a capire quali sono le righe di codice incriminate)

fracarro
07-08-2009, 17:14
Io di solito uso i flag -g e -O0 per utilizzare il profiler perché, come dice AnonimoVeneziano, in questa maniera il codice non viene "sporcato" dal compilatore e riesci a trovare i veri colli di bottiglia. Alla fine, quando pensi di aver fatto il massimo puoi dare una controllata anche con -O3, ma francamente non ho mai migliorato un granché (anche considerando che spesso i colli di bottiglia sono in funzioni inline e quindi diventa un casino, con O3, riuscire a capire quali sono le righe di codice incriminate)

Ok proverò con questi flag. Ma voi quale profiler usate? gprof, valgrind, netbeans?