Fai così, dovresti avere una precisione di circa 1.0E-6 (microsecondi) e comunque mi risolve anche tempi nell'ordine dell 1.0E-7 però per essere sicuro al 100% dovresti eseguire il processo in real time, ovvero senza condividere la CPU nè con il sistema nè con altri processi, se guardi la funzione GetCPUFrequency3 vedrai anche come fare a passare in real time.
Occhio che se il programma si impalla mentre sei in real time puoi solo resettare la macchina...
Perchè funzioni bisogna però che l'hardware supporti l'high-resolution performance counter (se non hai un computer antidiluviano dovresti averlo), e che windows lo riconosca.
codice:
#include <windows.h>
#include <iostream>
UINT64 inline rdtsc()
{
__asm{
RDTSC
}
}
//calcola frequenza CPU usando RDTSC come contatore di cicli di clock
//e usa QueryPerformanceCounter come timer ad alta risoluzione
//fornito da windows
double GetCPUFrequency3 (unsigned tempo_campionamento)
{
register UINT64 startC, endC;
UINT64 resFrequency, hrCounterFinal, hrCounterTemp = 0, step = 0;
double frequency; // In Hz.
if (QueryPerformanceFrequency (reinterpret_cast<LARGE_INTEGER*> ( & resFrequency)) == 0) return 0.0;
step = static_cast<UINT64> (static_cast<double> ( resFrequency) * (tempo_campionamento / 1000.0) );
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
startC = rdtsc();
QueryPerformanceCounter (reinterpret_cast<LARGE_INTEGER*> ( &hrCounterFinal));
//miglioramento possibile: valutare cicli clock chiamata QueryPerformanceCounter
hrCounterFinal += step;
while(hrCounterTemp < hrCounterFinal)
QueryPerformanceCounter (reinterpret_cast<LARGE_INTEGER*> (&hrCounterTemp));
endC = rdtsc();
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
frequency = (endC - startC) / (tempo_campionamento / (1000.0)); //10000
return frequency;
}
int main()
{
UINT64 inizio = rdtsc();
//per essere piu precisi bisognerebbe contare i
//cicli di clock persi durante la chiamata a rdtsc
//fai qualcosa
UINT64 fine = rdtsc();
UINT64 elapsed = fine - inizio;
double CPUFREQ = GetCPUFrequency3(1000);
//maggiore il tempo di campionamento maggiore la precisione
std::cout << elapsed << " cicli di CPU" << std::endl;
std::cout << static_cast<double> (elapsed) / CPUFREQ << " secondi " << std::endl;
return 0;
}