Newsgroup: it.comp.programmare.win32
Titolo: Api Tempo sotto NT

Salve
Vorrei sapere esiste un API sotto NT simile GetTickCount, pero con la
precisione almeno di 0.01 ms ...
Se non esiste vi faccio la seguente domanda come faccio a valutare
tempi così piccoli?
GP
Giuseppe Pugliares

 tempi così piccoli?
QueryPerformanceFrequency/QueryPerformanceCounter.  Non
credo che nessuna altra API possa misurare i tempi con precisione
di pochi microsecondi.
Alex

 tempi cosě piccoli?
Oltre ai performance/multimedia timers puoi sempre usare l'istruzione
RDTSC, che ha una *discreta* :-) definizione (il periodo di clock della
CPU sotto cui la esegui):
DWORD l,h;
_asm {
      rdtsc
      mov l,eax
      mov h,edx
     }
Non sono sicuro che il valore a 64 bit venga effettivamente restituito
in edx:eax, ma e` probabile. Inoltre ovviamente l'uso di tale istruzione
va "calibrato", nel senso che devi misurare la frequenza effettiva dei
tick (che cambia da CPU a CPU).
---
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/


Ti ringrazio molto per queste informazioni...
Ora ho ancora un piccolo problema, esiste qualche API che mi fornisca
la frequenza della CPU?
GP

 wrote in message
news:niNuOfOWCjZAXi...@4ax.com...


 la frequenza della CPU?
Puoi usare proprio RDTSC per scoprirlo. Leggi i ticks t1 con RDTSC, fai
una Sleep(T) (con T almeno di 2-3000 millisecondi), torni a leggere i
ticks t2 con RDTSC. Poi la frequenza in Hz e` data da (t2-t1)*1000/T.
Per curiosita` ho provato a farlo. Usando un T di tre secondi e`
abbastanza preciso, qui mi da` uno scarto circa dello 0.1% fra una
lettura e l'altra...
#include <windows.h>
#include <stdio.h>
#define T_SLEEP  3000
int main(int argc, char* argv[])
{
 unsigned __int64 t1,t2;
 DWORD l,h;
 DWORD m1, m2, f;
 _asm {
   rdtsc
   mov l,eax
   mov h,edx
  }
 t1 = (((unsigned __int64)h)<<32)+l;
 m1 = GetTickCount();
 Sleep( T_SLEEP);
 _asm {
   rdtsc
   mov l,eax
   mov h,edx
  }
 t2 = (((unsigned __int64)h)<<32)+l;
 m2 = GetTickCount();
 // (t2-t1)*1000/(m2-m1)
 f = (DWORD)((t2-t1)*1000/(m2-m1));
 printf( "Frequenza effettiva=%d\n", f);
 return 0;


lettura e l'altra...
Pure io ho fatto un paio di prove, è ho trovato il tempo di 5 sec come
un buon  compromesso tra velocità e precisione...
GP


Ho provato ad usare questa API, e facendo un po' di prove (unendo i
campi HighPart e LowPart in un __int64, oppure usando il campo
QuadPart) ottengo sempre lo stesso valore : 1193180 che dovrebbe
corrispondere ad una frequenza di circa 1.2 Mhz (invece di 337 Mhz),
sbaglio in qualche cosa?
GP

 wrote in message
news:619vOQdD1UtROL...@4ax.com...


I suggerimenti che t'hanno gia' dato sono perfettamente validi (su RDTSC
c'era pure un thread su comp.....nt.kernel-mode ), il problema della
risoluzione dei timer sotto NT (un po' meno sotto win2k per fortuna) e'
diciamo cosi' "annoso" (trovi articoli un po' d'appertutto DDJ, MSJ, WDJ,
etc.. nonch'e' nei vari books dedicati a DDK'ers ):
due articoli online di interesse potrebbero essere questi:
ftp://ftp.research.microsoft.com/pub/tr/tr-98-29.html
http://www.sysinternals.com/timer.htm
Saluti,
WalkerBoh

 un buon  compromesso tra velocità e precisione...
Credo che cio` che introduce la maggior parte dell'errore sia
GetTickCount(): temo che, al pari della maggior parte delle API "soft",
abbia una granularita` molto grezza e superiore a 1 ms.


 diciamo cosi' "annoso"
Beh, lo e` in praticamente tutti gli OS multitasking non realtime. Anche
per Linux c'e` una chiamata di sistema, usleep(), che dovrebbe fornire
una risoluzione di 1 us ma che in realta` ha la "solita" granularita` di
10 ms.


 10 ms.
in effetti e' vero.. cmq x NT c'e' da dire che codice "faraonico" e
meccanismi "barocchi" che mamma M$ ci mette (o meglio che documenta ;)
rendono il male piu' acuto =)
Saluti,
Walker Boh