__rdtsc frequency

Started by
4 comments, last by Kitt3n 17 years, 11 months ago
How do I find the frequency of the cpu so I can convert the rdtsc into milliseconds.
-----------------------------Language: C++API: Win32, DirectXCompiler: VC++ 2003
Advertisement
Using rdtsc is a bad idea in general (there are a lot of pitfalls). On Windows QueryPerformanceCounter and QueryPerformanceFrequency are your best bet, it's the easiest thing to use and works on multi-core systems.
If you must, then you can wait for a known length of time (Using Sleep() or something) and call rdtsc before and after it. Although Sleep() isn't incredibly accurate.
DWORD CalculateCPUSpeed(){DWORD dwTimerLo, dwTimerHi;const DWORD dwDelay = 500;	// We want absolute maximum priority	DWORD dwPriorityClass = GetPriorityClass(GetCurrentProcess());	int nPriority = GetThreadPriority(GetCurrentThread());	SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);	SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);	Sleep(0);	// Give up the rest of our timeslice so we don't get a context switch	// Get the current time stamp counter	__asm	{		rdtsc		mov dwTimerLo, eax		mov dwTimerHi, edx	}	// Sleep for a while    Sleep(dwDelay);	// Get the elapsed time	__asm	{		rdtsc		sub eax, dwTimerLo		sbb edx, dwTimerHi		mov dwTimerLo, eax		mov dwTimerHi, edx	}	// Reset priority and get speed	SetThreadPriority(GetCurrentThread(),nPriority);	SetPriorityClass(GetCurrentProcess(),dwPriorityClass);	return dwTimerLo / (1000*dwDelay);}


Alternatively, read it from the registry:
DWORD ReadCPUSpeedFromRegistry(){HKEY hKey;DWORD dwSpeed;	// Open the key	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,		"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\",0,		KEY_QUERY_VALUE,&hKey) != ERROR_SUCCESS)	{		return 0;	}	// Read the value	DWORD dwLen = 4;	if(RegQueryValueEx(hKey,"~MHz",NULL,NULL,(LPBYTE)&dwSpeed,&dwLen) != ERROR_SUCCESS)	{		RegCloseKey(hKey);		return 0;	}	// Cleanup and return	RegCloseKey(hKey);    return dwSpeed;}

Although that's just an estimate (So is what you'd get with Sleep()).
While not a direct answer to your question, I think this is a very good read:
Game Timing and Multicore Processors. Basically if you're intending your timing to also work on multicore targets, don't use RDTSC.
It seems not to be a good idea but you can do that on intel
( it will give you an approximation of the cpu proc using rdtsc ).

#include <iostream>#include <cstdlib>using namespace std ;static unsigned int hi = 0;static unsigned int lo = 0;void set_asm_counter( unsigned & hi , unsigned int & lo ){        __asm__ ( " rdtsc  ; movl %%edx , %0 ; movl %%eax , %1"                : "=r" (hi) , "=r" (lo)                :                :"%edx","%eax"                );}double get_asm_counter(const unsigned & hi_old , const unsigned & lo_old){        unsigned int new_hi = 0 ;        unsigned int new_lo = 0 ;        set_asm_counter(new_hi,new_lo) ;        unsigned int diff_hi = new_hi - hi_old ;        unsigned int diff_lo = new_lo - lo_old ;        unsigned int overflow_lo = lo_old  > diff_lo ;        diff_hi -= overflow_lo ;        return  static_cast<double> (diff_hi) * ( 0x1 << 30 ) * 4 + static_cast<double>(diff_lo ) ;}// purpose of main is here to give you a approximation of the proc freq int main(int argc,char * argv[]){        double res  = 0 ;// = get_asm_counter(hi,lo) ;        set_asm_counter(hi,lo) ;        cout << " timing value = " << res << endl ;        sleep(1) ;        res = get_asm_counter(hi,lo) ;        cout << " timing value = " << res << endl ;        return EXIT_SUCCESS ;}


good luck [rolleyes]
Check on www.intel.com for a doc on getting the cpu speed in MHZ.
That's what you need to convert rdtsc-ticks to seconds (or milliseconds).

rdtsc is not dualcore safe - but with a little effort can be made safe (I'm
using it on various machines, including amd 64 x2, intel-dualcore and
intel-HT)

It's a bit easier to use QueryPerformanceCounter, it will work with the
latest winXp patch installed (small patch released after sp2 if I remember
correctly), no idea about support for win2k though) - beware that not
everyone has this patch installed though!

rdtsc and queryPerformanceCounter are NOT speedstep-safe - you have to add
some additional code to see if the frequency changed (or ignore it -
especially laptops will have problem then, but speedstep is also coming
to the desktop pc's now).
visit my website at www.kalmiya.com

This topic is closed to new replies.

Advertisement