Newsgroup: it.comp.programmare.win32
Titolo: Profiling - 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).
Uso WinNT4, Borland C++ 5.0 (sigh!)
Ho provato clock(), ma ha una granularità troppo "coarse"!
Grazie, ciao
Per favore togliete "!RemoveMe!" dall'indirizzo per rispondere via email
Please remove "!RemoveMe!" from the address to email me

 frammenti di codice, come posso fare? Ci sono dei comandi apposta?
In generale si`, precisamente:
l'API QueryPerformanceFrequency ti torna (attraverso il suo
unico argomento, puntatore ad un intero di 64 bit, che essa
riempira`) il numero di tick/secondo per il performance clock;
la QueryPerformanceCounter, analogamente, ti torna il valore
attuale (numero di tick) del performance clock.
Se il tuo hardware non e` molto peculiare, dovresti poter
cosi` misurare i microsecondi o meglio.
La misura e` precisa sul tempo *trascorso*, ma non e`
naturalmente detto che sia trascorso tutto nei tuoi calcoli:
cache, memoria virtuale, altri thread/processi che vengono
in primo piano durante la misura, ecc ecc, possono tutti
allungare i tempi trascorsi.
Per affidabilita`, conviene ripetere la misura molte volte
(magari tenendo il thread ad alta priorita`) e prendere il
numero piu` favorevole (visto che tutti gli effetti di disturbo
allungano i tempi, nessuno li accorcia).
Se invece ti interessa proprio il tempo reale trascorso, perche`
DEVE stare entro un certo limite X, allora tieni il tuo thread
a performance normale e tienti un istogramma dei tempi di
esecuzione nelle moltissime volte che dovrai ripetere la
misura.  I sistemi Win32 non sono real-time, quindi garanzie
non se ne danno; dovrai decidere quale _probabilita`_ di
eccedere la soglia e` accettabile, e sulla base del tuo istogramma
calibrarla di conseguenza.
Alex

Unico appunto, tratto da MSDN per VC++:
"If the installed hardware supports a high-resolution performance counter,
the return value is nonzero.
If the installed hardware does not support a high-resolution performance
counter, the return value is zero."
con tanti saluti alla portabilita', in quanto il mio Alpha con NT ritorna
un bello 0!
Qualcuno me lo spiega?
--
____ __         __,_      __  _____
\  _\_ \  ___ _/ / /\  /\/  \/ / _/ 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

 Qualcuno me lo spiega?
Te lo spiega benissimo la parola "Alpha".  I SO Microsoft non hanno
mai supportato davvero bene nessuna CPU non compatibile Intel (con
la possibile eccezione di Win/CE, sul quale non so abbastanza per
pronunciarmi); la "portabilita`", se e quando scegli di usare dei SO
della Microsoft, la lasci comunque da parte.
Se il 'performance counter' non funziona sul tuo hardware (se non altro
e` fortunato che sia cosi` facile determinare che non funziona:-) il
tentativo successivo e` l'API GetProcessTimes, che pero` funziona
solo su NT, non su Windows/95 o /98.  Questa misura solo il tempo
effettivamente addebitato al tuo processo (in modalita` kernel e user),
quindi e` meno 'fragile' rispetto al carico multi-tasking ma anche, per
la stessa ragione, meno probante se quel che t'interessa e` comunque
sempre e solo il 'tempo reale trascorso'.  Inoltre, mentre la granularita`
teorica e` di 100 nanosecondi, vi e` potenzialmente lo stesso rischio
relativo alla funzione standard clock, di cui si discute su it.comp.lang.c++,
cioe` che questa teoria possa non corrispondere alla pratica, mentre
il 'performance counter', ove disponibile, gode di una granularita`
effettiva ben specificata (appunto da QueryPerformanceFrequency).
Ultima ratio (o giu` di li`) sono i "multimedia timer" -- anche per quelli
la disponibilita` dipende dall'hardware, non tanto pero` dalla CPU quanto
dalle tipiche periferiche 'multimediali', tipo schede audio.  Se li hai, da
essi puoi ottenere una granularita` garantita di 1 millisecondo (in teoria;
qui, pratica e teoria coincideranno se e solo se l'hardware e il relativo
driver rispettano le specifiche e non sono invece fatti a capocchia).
Alex

 Ho provato clock(), ma ha una granularità troppo "coarse"!
Anche se non riguarda strettamente la programmazione Windows, potresti
considerare di usare l'istruzione assembly (disponibile dai Pentium in avanti)
RDTSC, opcode 0x0F 0x31. Tale istruzione legge un contatore interno della CPU
che si incrementa - mi pare - a ogni ciclo di clock.
Probabilmente il contatore e` a 64 bit, quindi l'opcode 'depositera`' la
lettura su piu` registri. Non ricordo quali e in che ordine, ma facendo qualche
prova dovresti trovare questi dati senza problemi.
(piu` tardi) ho provato, il contatore viene depositato in EDX:EAX (quindi i 32
bit alti in EDX e i 32 bassi in EAX).
--
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/

 un bello 0!
Evidentemente per la piattaforma i386 si usa proprio l'istruzione RDTSC (vedi
altro mio msg), mentre Alpha non supporta istruzioni di questo genere (e` un
processore RISC, bella grazie se fa la somma fra interi ;-)).
Diventerebbe molto interessante scoprire se, e in quale modo, venga usata
RDTSC. Una buona ipotesi potrebbe essere quella che periodicamente venga fatta
una calibrazione per trovare la frequenza della CPU... dopodiche` traslare i
'ticks' di RDTSC in un delta temporale sarebbe semplice.
BTW, qualcuno di voi ha mai fatto caso a cosa succede all'output di
GetTickCount e dei timer multimediali in seguito all'utilizzo di SoftFSB e
simili?
