Newsgroup: it.comp.lang.c++
Titolo: Tempo di esecuzione istruzioni

Ciao a tutti,
sto cercando di capire un modo accurato per misurare il tempo di una
funziona, per chi segue il gruppo della porta COM, in particolare il
ReadFile() per leggere da porta COM.
Ho provato la funzione Clock() e GetTickCount(). Il programma è
questo:
int main() {
    double i;
    double time_i, time_f, t_tot;
double iStartTime = GetTickCount();
time_i=clock();
for(i=0; i<1000000; i++){}
time_f=clock();
double iEndTime = GetTickCount();
double iDiff = iEndTime - iStartTime;
t_tot=((time_f-time_i)/CLOCKS_PER_SEC)*1000;
cout << "Took " << iDiff << "ms" << endl;
cout << "Clock " << t_tot << "ms" << endl;
system("PAUSE");
return 0;
}
Ora qualcuno del gruppo mi aveva detto che il Clock() non era
accurato, ma se faccio partire il programma il risultato è:
-Clock() --> 6ms
-GetTickCount() --> 0ms
Esiste un modo più appropriato e più fine per misurare il tempo?
Ringrazio in anticipo tutti, soprattuto chi mi ha seguito fin'ora.

 }
E.


Ho ho cambiato, ma cmq sono double.
Cmq il risultato di tutto è sempre:
-took 0ms
-clock 5ms
P.S.: il codice ora è
int main() {
    double i;
    double time_i, time_f, t_tot;
int iStartTime = GetTickCount();
time_i=clock();
for(i=0; i<1000000; i++){}
time_f=clock();
int iEndTime = GetTickCount();
int iDiff = iEndTime - iStartTime;
t_tot=((time_f-time_i)*1000)/CLOCKS_PER_SEC;


 Esiste un modo più appropriato e più fine per misurare il tempo?
Su windows puoi usare QueryPerformanceCounter e 
QueryPerformanceFrequency (vedi 
http://msdn.microsoft.com/en-us/library/ms644904.aspx
 )
Su piattaforma x86 queste dovrebbero più o meno corrispondere alla RDTSC 
della CPU che ti ritorna il numero di clock passati dall'accensione 
(vedi 
http://en.wikipedia.org/wiki/Time_Stamp_Counter
 )
Con queste hai la massima precisione possibile: quella del clock della CPU
Ciao
GM



Sulle nuove piattaforme multi core ho letto che l'istruzione RDTSC non è 
più usata, perchè non fornisce risultati coerenti.
Ciao  Manlio Perillo

 
Hai qualche informazione in più?
Io lo uso senza problemi (a dire il vero uso le queryperformance di 
windows, ma mi sembra che sotto facciano comunque RDTSC)
O meglio una volta ho avuto problemi ma era una macchina "guasta" in cui 
ad un certo punto una delle due CPU ha incominciato a funzionare con un 
clock più basso.
In realtà in una macchina "sana" non credo questa sia una situazione 
tanto legale.
In questo caso bisognerebbe forzare il thread che prende i tempi a 
lavorare sempre sulla stessa CPU (o core) ma questo porta con se un 
certo overhead che potrebbe essere fastidioso.
Un'altra situazione a cui prestare attenzione, è quando sono attive 
tecnologie di risparmio energetico che potrebbero variare il clock alle 
CPU dinamicamente.
C'è un'articolo sul sito intel ma non ho avuto il tempo di leggerlo:
http://software.intel.com/en-us/articles/measure-code-sections-using-the-enhanced-timer
Del resto non saprei che altra tecnica si potrebbe usare per 
cronometrare precisamente il tempo consumato dal codice con una certa 
risoluzione...
GM

 dinamicamente.
Questa è una cosa a cui non avevo pensato. Tra l'altro viene cambiato 
dinamicamente e in modo indipendente la frequenza di ogni core. Quindi 
se non si è sotto carico "massimo" la "velocità" dipende da dove il/i 
thread sono allocati.
-- 
mio figlio: 
http://it.youtube.com/davideippopotamo
doppiatori: 
http://it.youtube.com/watch?v=hPGKNWZw0c0&feature=related
Articolo 33 della Costituzione italiana: L'arte e la scienza sono 
libere e libero ne è l'insegnamento.

 [...]
Ciao  Manlio

 
... che è lo stesso link che avevo postato io all'inizio :)
In effetti io non ho mai usato direttamente RDTSC ma ho sempre usato le 
api QueryPerformanceXXX di win.
Stando alla poca doc disponibile, sembra che queste API scelgano quale 
timer fisico usare a seconda di cosa c'è a disposizione. E' possibile 
che usino anche la RDTSC ma "mitigata" in qualche modo.
Salvo poi scoprire che la MS stessa avverte che ci possono essere bug 
vari nei bios o altrove che la rendono non perfetta (oltre ad avere un 
po di overhead rispetto alla RDTSC secca). Tant'è che consigliano di 
tenere l'affinità del thread che prende i tempi su una sola CPU!.
http://msdn.microsoft.com/en-us/library/bb173458.aspx
Comunque credo che le QueryPerformanceXXX siano il compromesso migliore
(ovviamente su win).
Bye.
GM

 GM
Ciao  Manlio Perillo

 Ringrazio in anticipo tutti, soprattuto chi mi ha seguito fin'ora.
esempio di utilizzo delle funzioni GetTickCount e QueryPerformanceCounter:
int i;
DWORD dwTimerNew;
DWORD dwElapsed;
DWORD dwTimerOld = GetTickCount();
for (i = 0; i < 100; i++)
{
	Sleep(1);
	dwTimerNew = GetTickCount();
	dwElapsed = dwTimerNew - dwTimerOld;
	dwTimerOld = dwTimerNew;
	TRACE("GetTickCount = %d\n", dwElapsed);
}
LARGE_INTEGER li;
QueryPerformanceFrequency( &li );
double dQPFTicksPerMilliSec = double(li.QuadPart) / 1000.0;
LONGLONG llTimerNew;
double dElapsed;
QueryPerformanceCounter(&li);
LONGLONG llTimerOld = li.QuadPart;
for (i = 0; i < 100; i++)
{
	Sleep(1);
	QueryPerformanceCounter(&li);
	llTimerNew = li.QuadPart;
	dElapsed = double(llTimerNew - llTimerOld) / dQPFTicksPerMilliSec;
	llTimerOld = llTimerNew;
	TRACE("QueryPerformanceCounter = %f\n", dElapsed);
}

 > Esiste un modo più appropriato e più fine per misurare il tempo?

GRAZIEEEEEE!!!!
Grazie di tutto.
Finalmente con questo esempio ho capito....
Non capivo xkè ci fossero tutto quelgi zeri e all'improvviso 16ms