<!-- Download Links -->
<!-- Article image -->
<!-- Add the rest of your HTML here -->
Introduction
CPUTest is a just a small class (CCPU
) with a few static
member functions. It calculates the frequency of the CPU in 50ms.
How it works
The idea is pretty simple, and it has been implemented many times. All modern processors (Pentium+) have a TimeStamp Counter (TSC), which is incremented once every clock cycle. Read the TSC, delay for some time, read the TSC again and get the difference of the two Timestamps (the result is in clock cycles). Divide the cycles by the delay time and you get the frequency.
What's Cool
Most Get-CPU-MHz implementations use Sleep()
to delay. The problem with Sleep()
is that it's not so accurate, especially when using it for small delays. You have to delay at least 1000 msecs to get a fair result.
To overcome this problem, I used the QueryPerformanceFrequency()
and QueryPerformanceCounter()
functions.
Take a look at this function, which is a private member of CCPU.
static void _Delay(unsigned int ms)
{
LARGE_INTEGER freq, c1, c2;
__int64 x;
if (!QueryPerformanceFrequency(&freq))
return;
x = freq.QuadPart/1000*ms;
QueryPerformanceCounter(&c1);
do
{
QueryPerformanceCounter(&c2);
}while(c2.QuadPart-c1.QuadPart < x);
}
This delay function is fairly accurate, even for small periods.
Moreover, there's a _DelayOverhead()
function, which is used by GetMHz()
(see below) to calculate the overhead of calling this function and subtract it from the result.
Also, the GetMHz()
(see below) function has the ability to change the Process Priority Class and the Thread Priority, so the results are more accurate. When finished, it restores the PC and TP to their previous settings.
As a result of all this, a single call to GetMHz()
is enough to get the MHz of the CPU, and it takes only 50ms to complete!
int mhz = CCPU::GetMHz();
CCPU class Functions
There is only one class, the CCPU
class. It contains only static
member functions and no data.
The functions are:
static unsigned int ReadTimeStampCounterLow();
static unsigned int ReadTimeStampCounterHigh();
static unsigned __int64 ReadTimeStampCounter();
static void ReadTimeStampCounter(unsigned int *uHigh, unsigned int *uLow);
static __int64 GetCyclesDifference(CCPU_FUNC func, unsigned int param);
static int GetMHz(unsigned int uTimes=1, unsigned int uMsecPerTime=50,
int nThreadPriority=THREAD_PRIORITY_TIME_CRITICAL,
DWORD dwPriorityClass=REALTIME_PRIORITY_CLASS);
Conclusion
Hope you find this code useful; sure hope it works ;-).
And by the way, if you run the demo, post your CPU's frequency and the results you get here, especially if it's totally wrong.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.