Click here to Skip to main content
15,881,852 members
Articles / Programming Languages / C++

CPUTest

Rate me:
Please Sign up or sign in to vote.
4.78/5 (19 votes)
18 Apr 2001CPOL2 min read 239K   3.6K   41   61
Simple class to calculate the frequency of the CPU in MHz
<!-- Download Links --> <!-- Article image -->

Sample Image - CPUTest.gif

<!-- 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.

// Delays for the specified amount of milliseconds
static	void	_Delay(unsigned int ms)
{
   LARGE_INTEGER	freq, c1, c2;
	__int64		x;

   // Get High-Res Timer frequency
	if (!QueryPerformanceFrequency(&freq))	
		return;
		
	// Convert ms to High-Res Timer value
	x = freq.QuadPart/1000*ms;		

   // Get first snapshot of High-Res Timer value
	QueryPerformanceCounter(&c1);		
	do
	{
            // Get second snapshot
	    QueryPerformanceCounter(&c2);	
	}while(c2.QuadPart-c1.QuadPart < x);
	// Loop while (second-first < 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:

// The TSC is 64 bit. This function returns the low part
static unsigned int ReadTimeStampCounterLow();

// This returns the high part
static unsigned int ReadTimeStampCounterHigh();

// Returns the TSC, as an unsigned __int64
static unsigned __int64 ReadTimeStampCounter();

// Puts TSC in uHigh and uLow
static void ReadTimeStampCounter(unsigned int *uHigh, unsigned int *uLow);

// This will call the function 'func' with parameter 'param' and 
// return the difference in clock cycles.
// 'func' must be a pointer to function of this type: 
// void my_func(unsigned int param);
static __int64 GetCyclesDifference(CCPU_FUNC func, unsigned int param);

//
// Returns the MHz of the CPU
//
// Parameter             Description
// ------------------    ---------------------------------------------------
//    uTimes             The number of times to run the test. The function
//                       runs the test this number of times and returns the
//                       average. Defaults to 1.
//    uMsecPerTime       Milliseconds each test will run. Defaults to 50.
//    nThreadPriority    If different than THREAD_PRIORITY_ERROR_RETURN,
//                       it will set the current thread's priority to
//                       this value, and will restore it when the tests
//                       finish. Defaults to THREAD_PRIORITY_TIME_CRITICAL.
//    dwPriorityClass    If different than 0, it will set the current
//                       process's priority class to this value, and will
//                       restore it when the tests finish.
//                       Defaults to REALTIME_PRIORITY_CLASS.
//
// Notes
// -------------------------------------------------------------------------
// 1. The default parameter values should be ok.
//    However, the result may be wrong if (for example) the cache
//    is flushing to the hard disk at the time of the test.
// 2. Requires a Pentium+ class processor (RDTSC)
// 3. Requires support of high resolution timer. Most (if not all) Windows
//    machines are ok.
//
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Greece Greece
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionLicense Pin
Member 210973022-Oct-12 0:09
Member 210973022-Oct-12 0:09 
AnswerRe: License Pin
Pavlos Touboulidis26-Oct-12 3:39
Pavlos Touboulidis26-Oct-12 3:39 
Member 2109730 wrote:
I would like to know if I can use this code in a commercial product.

Sure, go ahead! This code is so old it should be considered public domain anyway.
GeneralCPU temperature Pin
nta_388623-Aug-08 23:03
nta_388623-Aug-08 23:03 
GeneralUseful Pin
VS_Study7-Jun-08 6:09
VS_Study7-Jun-08 6:09 
Questionhow can i get cpu temperature ? can you help me? Pin
lgbean10-Jan-08 12:13
lgbean10-Jan-08 12:13 
Generalit can run on the platform of mobilePhone or smartphone Pin
llfxiumei12-Apr-07 20:15
llfxiumei12-Apr-07 20:15 
QuestionHow to enable COM service in windows? Pin
bharath7118022-Feb-06 22:48
bharath7118022-Feb-06 22:48 
GeneralNicely Done Pin
Paul Conrad3-Jan-06 6:22
professionalPaul Conrad3-Jan-06 6:22 
GeneralSystems With Multiple Processors Pin
F e r o z Z a h i d3-Sep-04 11:50
sussF e r o z Z a h i d3-Sep-04 11:50 
GeneralSeems Accurate Pin
Stephen Sweeney8-Jun-04 4:15
Stephen Sweeney8-Jun-04 4:15 
GeneralRe: Seems Accurate Pin
dzonithegood26-Apr-10 11:52
dzonithegood26-Apr-10 11:52 
QuestionHow to round Pin
Jeff Bogan13-Apr-04 4:37
Jeff Bogan13-Apr-04 4:37 
Generalhelp !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!controlling web cam using VC++ Pin
sanxay14-Dec-03 22:52
sanxay14-Dec-03 22:52 
GeneralRe: help !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!controlling web cam using VC++ Pin
megatof6-Sep-04 1:45
megatof6-Sep-04 1:45 
GeneralAlternate to CCPU_I32TO64 macro and other notes Pin
Joe Woodbury22-Dec-02 6:42
professionalJoe Woodbury22-Dec-02 6:42 
GeneralSpin controls reversed Pin
Joe Woodbury22-Dec-02 6:34
professionalJoe Woodbury22-Dec-02 6:34 
GeneralUseful and Accurate. Pin
Brian Delahunty21-Sep-02 3:39
Brian Delahunty21-Sep-02 3:39 
General857 - Athlon 850 Pin
Daniel Turini16-Aug-02 21:31
Daniel Turini16-Aug-02 21:31 
GeneralRe: 857 - Athlon 850 Pin
Brian Delahunty21-Sep-02 3:31
Brian Delahunty21-Sep-02 3:31 
GeneralUseful Pin
Anthony_Yio16-Aug-02 21:10
Anthony_Yio16-Aug-02 21:10 
GeneralRe: Useful Pin
Brian Delahunty21-Sep-02 3:32
Brian Delahunty21-Sep-02 3:32 
GeneralGood Pin
Mukkie21-Jul-02 6:20
Mukkie21-Jul-02 6:20 
GeneralI hate to be a pain but... Pin
Ryan Binns1-Jul-02 2:28
Ryan Binns1-Jul-02 2:28 
GeneralRe: I hate to be a pain but... Pin
Ryan Binns1-Jul-02 2:33
Ryan Binns1-Jul-02 2:33 
GeneralRe: I hate to be a pain but... Pin
Brian Delahunty21-Sep-02 3:33
Brian Delahunty21-Sep-02 3:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.