Newsgroup: it.comp.lang.c
Titolo: Time

Ciao a tutti,
ho appena scritto un pezzo di codice ( linguaggio C)  che implementa un
certo algoritmo e vorrei saper quanto tempo č impiegato per eseguire tale
codice, la risoluzione che cerco č del micro-secondo.Grazie per la
collaborazione.


Se hai Win9x/ME puoi usare QueryPerformanceCounter() insieme a
QueryPerformanceFrequency().
Solitamente la frequenza č 1193180 Hz per cui fa proprio al caso tuo.
Cristiano

Se usi PC della classe Pentium o successivi potrai accedere alla massima
precisione possibile usando l'istruzione assembler RDTSC che restituisce nei
registri EDX:EAX un unsigned long long (64bit) che contiene il numero di
cicli di clock della CPU che sono trascorsi dall'avvio del PC. Ti faccio
notare che con un 1GHz la risoluzione è di 1ns ... molto ma molto buona :-)
... se usi questa strada ti avverto che noterai alcune "stranezze". Ad
esempio se monitorizzi una singola espressione C noterai una discreta
differenza di tempo impiegato ad eseguirla la prima volta rispetto alle
successive ... si tratta degli effetti delle innumerevoli ottimizzazioni che
entrano in gioco nei computer moderni e rendono un monitoraggio dei tempi
un'attività statistica più che una misurazione assoluta (A meno che tu non
conosca tutti le regole ed i trucchi usati per implementare queste
ottimizzazioni ... ma resta comunque un'impresa). Non vorrei che quello che
ho detto suoni come "è inutile che fai le misurazioni tanto ti forniscono
dati ballerini" infatti non è questo quello che intendevo ma volevo solo
chiarire che se si cerca una misura precisa al ciclo di CPU allora si va
incontro a questi problemi e dunque ti ho voluto evitare brutte sorprese, le
misurazioni pui farle tranquillamente, basta che sai gestire i risultati che
ottieni :)
Ciao e buon lavoro
Alessio C.

 dall'avvio del PC. 
1 - unsigned long long non e' standard (o mi sono perso qualcosa?)
2 - ricordiamoci che per avere un vero timer portabile (e comunque
    solo su x86) occorre anche sapere quanti cicli ha la CPU, e a meno 
    di farne una versione personale, da modificare ad ogni cambio CPU,
    si deve tener conto del clock

 1 - unsigned long long non e' standard (o mi sono perso qualcosa?)
E` previsto dal C99
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Ci sono due cose che l'uomo non puo` nascondere:
essere ubriaco ed essere innamorato.

     si deve tener conto del clock
Esatto occorre sapere a che frequenza va la CPU ...
500MHz -> 2ns per ciclo
1GHz -> 1ns per ciclo
ecc :)
Ciao
Alessio C.

 ha scritto nel messaggio
news:a4eapj$nji$1...@pegasus.tiscalinet.it...


"Carlini Alessio" ha scritto:

Purtroppo la frequenza che viene riportata è quella nominale. Facendo alcune
prove su cpu di diverso tipo ho notato che la frequenza reale varia
abbastanza da quella nominale.
Io determino la frequenza del TSC con questo frammento di codice:
  typedef unsigned __int64 UI64;
UI64 RDTSC(void)
{
 unsigned long TS[2],*pTS=TS;
 asm {
  push eax      // Save registers we will overwrite (eax, ebx, edx).
  push ebx
  push edx
  DB 15    // The RDTSC instruction consists of these two bytes.
  DB 49
  mov ebx, pTS // Put the address where the timestamp goes in ebx.
  mov [ebx],eax   // Save low 4 bytes of timestamp there.
  mov [ebx+4],edx // Save high 4 bytes of timestamp next.
  pop edx         // Restore overwritten registers.
  pop ebx
  pop eax
 }
 return UI64(TS[1])<<32 | TS[0];
}
  LARGE_INTEGER ti,tf,freq;
  QueryPerformanceFrequency(&freq);
  // Calcolo tempi morti
  QueryPerformanceCounter(&ti);
  UI64 T0 = RDTSC(); UI64 T1 = RDTSC();
  QueryPerformanceCounter(&tf);
   int Tm = tf.QuadPart - ti.QuadPart;
  // Calcolo frequenza
  QueryPerformanceCounter(&ti);
  T0 = RDTSC(); Sleep(500); T1 = RDTSC();
  QueryPerformanceCounter(&tf);
   int PC = tf.QuadPart - ti.QuadPart;
  double T = (T1 - T0 - Tm) / double(PC) * freq.QuadPart;
Mi scuso per aver postato roba assolutamente non standard ma mi sembra che
possa interessare a completamento del discorso.
Cristiano

 operativo su cui lavoro e` Linux
Allora  la soluzione  e` gettimeofday(3)  usata sul  processo schedulato
rigorosamente in RT.
Per ulteriori info: it.comp.os.linux.development.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Io mi ricordo sempre il compleanno della mia ragazza:
cade il giorno dopo di quando lei me lo ricorda

 schedulato rigorosamente in RT.
be', ovviamente funge anche la rdtsc, su pentium

 abbastanza da quella nominale.
E' vero ma il metodo che hai usato tu per verificarlo ha la pecca di avere a
sua volta lo stesso difetto dunque il risultato che hai conseguito e che tu
attribuisci alla RDTSC in realtà è dovuto in buona parte proprio al tuo
metodo di misura.
Ho usato la RDTSC proprio per la sua alta risoluzione conscio nel fatto che
la sua precisione è legata a quella del quarzo come paraltro quella della
QueryPerformanceCounter(); che usi tu come misura ma al contrario di questa
la lettura di RDTSC avviene direttamente dal processore mentre la
QueryPerformanceCounter() deve fare un accesso all'I/O che introduce alcuni
microsecondi di latenza.
Io quando uso la RDTSC lo faccio contando solo su queste proprietà:
1) Alta risoluzione (Un tick vale un ciclo di clock della CPU)
2) Ottima precisione (Quarzo)
Se voglio anche un tempo assoluto allora il metodo più preciso che ho è
quello di cronometrare, con un buon coronometro, la durata di una lungo loop
(Qualche ora) che a sua volta è monitorata tramite RDTSC ed alla fine
trovare quanto vale con precisione il cilco di CPU. Ti faccio notare che la
discrepanza dal valore nominale nei casi che ho provato io era minore del
0.1%. Ultimo consiglio ... se vorrai provare anche tu sappi che è importante
nel cronometraggio che sia nella partenza che nell'arrivo tu usi una tecnica
omogenea, ad esempio se avvii premendo un tasto devi terminarlo allo stesso
modo anche se io ti consiglio un avvio ed una terminazione al volo ... su
video compare la scritta INIZIO e poi alla fine FINE, in questo modo non hai
latenze aggiuntive e ci si aspetta che il tuo tempo di reazione sia simile
in entrambi i casi :).
Ciao e fammi sapere ... magari in privato visto che continuiamo ad essere OT
:$
Alessio C.


ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Sei l'unica donna della mia vita".
(Adamo)