Newsgroup: it.comp.lang.c++
Titolo: Valutazione delle prestazioni

Ciao!
Mi serve una stima affidabile dei tempi di esecuzione di alcuni
frammenti di codice, come posso fare? Ci sono dei comandi apposta?
Mi spiego meglio, vorrei fare una cosa tipo
// codice prima
double t;
start_chrono(); 
//inizio sezione critica
// bla bla ...
//fine sezione critica
t = stop_chrono();
cout << "Tempo trascorso: " << t;
Non dispongo di tool tipo debugger o altro (incredibile).
Grazie, ciao
Per favore togliete "!RemoveMe!" dall'indirizzo per rispondere via email
Please remove "!RemoveMe!" from the address to email me

 Non dispongo di tool tipo debugger o altro (incredibile).
L'unica funzione portabile per fare cio` che desideri e` time,
che purtroppo ha una granularita` di un secondo, quindi serve
solo se la tua "sezione critica" richiede molte decine di secondi.
Se no, devi ricorrere ad approcci tipici di una data piattaforma,
e quindi chiedi sul newsgroup che copre la piattaforma di tuo
specifico interesse (it.comp.programmare.win32 se e` Windows
a 32 bit, ecc, ecc).
Alex

 wrote in message
85ch6s$l7c$1...@serv1.iunet.it...
: L'unica funzione portabile per fare cio` che desideri e` time,
: che purtroppo ha una granularita` di un secondo, quindi serve
: solo se la tua "sezione critica" richiede molte decine di secondi.
Scendi un attimo dalla cattedra, oppure usa toni + moderati... anche in
altre risposte
A me risulta la f. clock(), libreria std del C, definita da ANSI 
4.12.2.1
:
"The clock function's era begins (with a value of 0) when the C program
starts to execute. It returns times measured in 1/CLOCKS_PER_SEC"
e di solito CLOCKS_PER_SEC vale 1000, quindi disponi di granularita' a un
millesimo di secondo, sufficiente per il profiling, secondo me.
esempio d'uso:
#include <stdio.h>
#include <time.h>
int main( void )
{
   clock_t inizio, fine;
   double  durata;
   inizio = clock();
   // codice da eseguire
   fine = clock();
   durata = (double)(fine - inizio) / CLOCKS_PER_SEC;
   printf( "La durata e' di %02.3f secondi\n", durata );
   return 0;
}
--
____ __         __,_      __  _____
\  _\_ \  ___ _/ / /\  /\/  \/ / _/ It is better to reign in Hell
 \  _ \ \/ _ '/ , |\ VV / / / / _/ Than serve in Heaven.- MILTON
  \_,_/\_\_,_/_/|_| \__/\__/_/_/
      -- the one and only --     e-mail : 
blak...@tiscalinet.it
                                ICQ    : 59394345
The UNIX Guru's View of Sex:
$unzip;strip;touch;finger;mount;fsck;more;yes;umount;sleep

 altre risposte
Stavo "in cattedra" (come professore universitario) vari anni fa,
ma poi ho trovato molto piu` divertente (e lucrativo) tornare "in
trincea", a _sviluppare_ veramente software all'avanguardia,
piuttosto che non a insegnarlo e a teorizzarci su.
Quindi, "grazie" (si fa per dire!-) del consiglio, ma dalla cattedra
ci sono sceso da un po', e non ho particolare desiderio di tornarci:-).
Quanto ai "toni moderati", qui e "in altre risposte", che intendi mai?
Io, ovviamente, dico le cose come secondo me stanno; se non lo so
(e so di non saperlo:-), non ne parlo, o esprimo pareri dubitativi; se
lo so (o credo di saperlo:-) non usero` certo un tono "dubbioso", ti
pare?  Di solito sono fin troppo prolisso, in questo caso apparentemente
sono stato invece troppo conciso (non spiegando perche` non ritengo
clock inadatta ad uso portabile -- spero con questo post di avere
compensato).  Non si tratta di "moderazione", ma di tempo e voglia
di scrivere centinaia invece che decine di righe!-)
Che mai vorresti, o sventurato, che se qualcuno chiede "come si
fa a dire ad una classe di ereditare da un'altra" le risposte fossero
del tenore di "Mah, non sono sicuro, pero`, se non sbaglio, un
modo che bene o male dovrebbe di solito quasi funzionare nella
maggior parte dei casi (se sbaglio mi corigerete) potrebbe essere
quello di scrivere qualcosa di simile a 'class Deriv: public Base {'"...?!-)
Una simile untuosa ipocrisia di finta umilta` mi rivolterebbe.  Mille
volte meglio leggere una concisa risposta di "Scrivi 'class Deriv: public
Base {'", anche se poi magari qualcuno dovra` fare un follow-up per
spiegare che il "public" non e` obbligatorio, esiste anche l'eredita`
privata, e quella protected, e...:-).
Alex

altre risposte
Hai attaccato la persona sbagliata. Martelli e' il piu' disponibile e il
meno "presuntuoso" in questo (e non solo) ng.
Marco

 


Ti ricordo che il profiling serve a stabilire qual'e' la parte di codice
piu' pesante, e che loop di 20 iterazioni sono _RIDICOLI_, se in ogni
iterazione usi solo la printf(), ma diventano significativi in caso di
operazioni complesse. La printf e' implementata in modo da richiedere
pochissimi cicli di CPU, quindi su un vecchio P133, ti serve una
granularità di _almeno_ 10^-8, cioe' siamo vicini ai nanosecondi. ti sfido
a trovare tale precisione, anche su CRAY.
Inoltre CLOCKS_PER_SEC dipende dal *compilatore*, non dal sistema. E per di
piu' scritto nella forma
tempo = (double)(fine - inizio) / CLOCKS_PER_SEC;
la variabile tempo e' INDIPENDENTE dal suo valore, ma solo + o meno
preciso. E ripeto che una precisione di 1/60 di sec va benissimo per il
profiling, molto meglio di 1sec, che tu ritenevi essere il massimo in fatto
di portabilita'.
L'esempio che riporti, poi e' errato, in quanto interponi delle operazioni
non elementari tra le due clock(), come la stampa a video di pochi
caratteri non bufferizzati e la conversione da clock_t a int, come hai
dichiarato le variabili. In questo modo stai calcolando l'intervallo tra le
printf, in quanto new_clock assume sempre valori maggiori dell'unita'
immediatamente superiore.
Una versione piu' corretta e' la seguente:
    clock_t start, end, old_clock=0, new_clock;
    int i; double time;
    start = clock();
    for(i=0; i<20; ++i){
        while((new_clock=clock())==old_clock);
        old_clock = new_clock;
    }
    end = clock();
    time = (double)(end - start) / CLOCKS_PER_SEC;
    printf ("start: %d \t end: %d\n", start, end);
    printf("clock totali:%d clock per ciclo:%2.2f\n", end - start,(float)
(end -  start)/20.);
    printf ("Secondi impiegati per 20 cicli %2.3f\n", time);
su unix:
$ cc prova.c -O4
$ ./a.out
start: 3114362   end: 3114545
clock totali:183 clock per ciclo:9.15
Secondi impiegati per 20 cicli 0.183
$
molto diverso da quello che affermi. Quanto al resto del msg, sono proprio
i toni decisi che danno l'aria da Signor Sotutto. Un po' di educazione, sia
nelle risposte che nelle correzioni, fa vivere meglio e crea un'atmosfera +
creativa. Spero (per te) che tu non insegni, o almeno che insegnando usi un
altro approccio.
E te lo dico da insegnante.
saluti


 meno "presuntuoso" in questo (e non solo) ng.
Infatti, solo che a volte la sua sterminata cultura viene scambiata per
presunzione.
EMG

 wrote in message
387A197F...@freelance.it...
: Purtroppo lo standard in questo caso non ti aiuta molto.
: Chi ti aiuta e' l'esperienza.
: E l'esperienza mi porta a dire che Alex ha piu' che ragione.
:
: Per quanto riguarda questo "scendere dal pero", beh mi sembra un
: tantinello presuntuoso.
Ok, mi sono riletto altri msg e concordo con te. Forse mi sono inalberato
perche' ho la luna di traverso e chiedo scusa per aver tirato in ballo la
superbia.
Scusa, Alex.
Ritratto anche l'ultima affermazione sull'insegnamento, ho visto esempi che
mi hanno fatto ricredere.


>
Mi permetto di inserirmi in questa discussione anche se sta diventando OT per dire la mia.
Dire che lo standard non ti aiuta non vuol certo dire che sia meglio usare time() anziche' clock(). In questo caso la risposta piu' corretta e' dire usa clock() ma provane la bonta'.
Tra l'altro anche Alex ha provato clock() per dimostrare che non ha la precisione di un millesimo ma non ha provato time() per dimostrare che ha la precisione di un secondo (o magari lo ha fatto ma non lo ha scritto).
Penso che Alex Martelli sia di gran lunga il piu' preparato su questo NG ma cio' non toglie che spesso si e' trovato "impelagato" in discussioni polemiche con piu' di una persona (tra le quali anche me per una discussione sul C++ e Java).
Anche in questo caso mi sembra che dire che non aveva fatto cenno della funzione clock perche' non la riteneva appropriata mi sembra un modo di nascondere la verita'  (ed in questo caso scendi dalla cattedra ci sta anche bene). Peraltro Alex non ha bisogno di nessuna dimostrazione delle sue capacita' (a mio giudizio) perche' ha dato ampie prove in tutti questi mesi.
Antonio

 > a 32 bit, ecc, ecc).
Altrettanto corretto.
L'argomento iniziale era:
	"Mi serve una stima affidabile dei tempi di esecuzione 
         di alcuni frammenti di codice, come posso fare? ....."
Perche' "e' la risposta piu' corretta" usare clock()?
Non e' vero. NOn e' assolutamente vero. Alex te l'ha
dimostrato. Cosa vuoi di piu'.
Fausto.

 E te lo dico da insegnante.
Nonostante sia reduce da recenti bastonature proprio da parte sua, mi
sento di prendere le difese di Alex Martelli. Mi pare in assoluto e da
diversi mesi la persona che piu' contribuisce al contenuto informativo
di questo newsgroup; mostra una padronanza del linguaggio ed una cultura
rispetto a cio' che vi sta intorno decisamente superiori alla media
(anche dei frequentatori del gruppo, per quanto si puo' evincere dalla
lettura dei messaggi) ed e' ben disposto a dividerle con altri, fornendo
molto spesso risposte chiare, organiche e circostanziate a domande di
qualsiasi livello.
Trovo che solo raramente scivola nella saccenza (e di solito solo quando
lo si punzecchia :-) e mi pare un difetto assolutamente trascurabile se
paragonato al suo contributo al gruppo. Continua cosi', Alex!
Ciao,
Nicola

 Una versione piu' corretta e' la seguente:
[...]
Sei sicuro che faccia la stessa cosa dell'originale?
	Mauro

 wrote in message
: E allora? Vorresti fare 100000 iterazioni quando per
: quello che deve fare il programma (mostrare la granularita'
: di clock()) ne bastano una decina?
No. Casomai il fatto che discerna tra 20 cicli di printf mi sembra
"adeguato al profiling, origine della discussione.
: Potrebbe non funzionare bene con una granularita' di clock()
: molto fine e/o una printf molto lenta, ma non direi che e'
: errato.
: Se non ti funziona bene (i valori stampati non sono chiaramente
: multipli), puoi limitarti a memorizzare i valori per poi
: stamparli sucessivamente.
Il programma voleva mostrare l'intervallo tra un clock e l'altro, in
quanto, finche' uguali, era in loop continuo.
: > dichiarato le variabili. In questo modo stai calcolando l'intervallo
tra le
: > printf, in quanto new_clock assume sempre valori maggiori dell'unita'
: > immediatamente superiore.
:
: Cioe?
cioe' passa + di un clock tra un ciclo e l'altro, anche se fai op. come
printf, e quindi la granularita' e' sufficiente.
: > Una versione piu' corretta e' la seguente:
: [...]
:
: Sei sicuro che faccia la stessa cosa dell'originale?
No. non lo fa. l'originale misurava printf in clock, dopo averne atteso al
minimo uno, per via del ciclo, la mia mostra che il tempo per 20 cicli di
clock e' _inferiore_ al tempo di paragone, altrimenti il risultato sarebbe
esattamente 20, o poco piu', per via del tempo di uscita dal ciclo e della
call alla clock finale.
ciao.


 su unix:
Come se ci fosse UNO "unix"...!  "ma mi facci il piacere",
avrebbe detto il grande Toto`.
Puo` benissimo darsi che UNA particolare piattaforma in tuo
attuale possesso abbia un CLOCKS_PER_SEC di 1000 e,
mirabile dictu, *anche* una vera granularita` di 1000 clock
al secondo (dal tuo programma, il cui scopo non mi e`
d'altronde per nulla chiaro, non e` facile dirlo).  Se anche
e` cosi`, in che modo questo smentirebbe quanto da me
affermato sulla portabilita`...?!  "Portabile" non significa
"funziona bene su di una piattaforma che oggi usa Blak",
almeno non secondo il mio abituale vocabolario.
Bah.  Che c'entri qualcosa quella citazione da Milton...?
Tutto sommato, se questo gruppo e` "heavenly", nel senso
che vi si vedono molte risposte di buona qualita`, ma Blak
non vi e` "il migliore", si puo` dire che non vi "regna"; sulla
falsariga della citazione, potrebbe dunque preferire farne uno
"Hell", sul quale pero` regnare incontrastato....?-)
Alex

 printf, e quindi la granularita' e' sufficiente.
Non necessariamente.
Per esempio, su Debian 2.1 stampa:
 
  CLOCKS_PER_SEC = 1000000
  10000
  20000
  30000
  40000
....
  180000
  190000
  200000
 
Questo non vuol dire che la printf ci mette 10000 clock (10 ms),
ma che la granularita' di clock() e' di 10ms (1/100 di sec)
anche se CLOCKS_PER_SEC vale 1000000.  In pratica il valore
di clock() viene aggiornato ogni 10ms e incrementato di 10000
alla volta.
Da quello che ha detto Alex, anche su NT la situazione e' simile
(CLOCKS_PER_SEC = 1000, ma aggiornato ogni 10ms e incrementato
di 10 alla volta).
Se sul tuo sistema non succede cosi, e invece i valori stampati
dal programma differiscono di poche unita' in maniera irregolare,
vuol dire che il tuo sistema ha una buona granularita'.
In programmi portabili pero' non ci si puo' fare affidamento,
e bisogna aspettarsi granularita' modeste, anche in sistemi
con CLOCKS_PER_SECS elevato.
	Mauro

 ha scritto:


>dimostrato. Cosa vuoi di piu'.
Non mi sembra che abbia dimostrato che clock() ha una precisione piu' bassa di time().
Antonio