Introduction
I'll show you two ways to retrieve the processor-speed (frequency in MHz). With two simple functions, one to retrieve the frequency from the registry of your Windows operating system, and one to calculate it with the clock cycles and a high resolution counter. If you want to use the function to calculate the speed (frequency), you have to use it with a Pentium instruction set compatible processor (look at the lines below).
rfmobile wrote in a message:
You don't need to change the RDTSC definition for non-Intel processors. The code works as-is on my AMD mobile Athlon. Should work on any Pentium instruction set compatible processor but not for 486 or 386.
I'm not able to verify this, so I would like to hear some feedback.
BTW: Constructive criticism is always welcome! :-)
Routine to retrieve the speed (frequency) from the registry:
This is plain code to retrieve a registry value as a CString
:
CString ProcSpeedRead()
{
CString sMHz;
char Buffer[_MAX_PATH];
DWORD BufSize = _MAX_PATH;
DWORD dwMHz = _MAX_PATH;
HKEY hKey;
long lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
0,
KEY_READ,
&hKey);
if(lError != ERROR_SUCCESS)
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lError,
0,
Buffer,
_MAX_PATH,
0);
AfxMessageBox(Buffer);
return "N/A";
}
RegQueryValueEx(hKey, "~MHz", NULL, NULL, (LPBYTE) &dwMHz, &BufSize);
sMHz.Format("%i", dwMHz);
return sMHz;
}
Routine to calculate the processor frequency in MHz:
Retrieve the frequency in MHz as a float
ing-point number. I use some well documented (at least for me ;-)) assembler here:
float CGettheProcessorSpeedDlg::ProcSpeedCalc()
{
#define RdTSC __asm _emit 0x0f __asm _emit 0x31
__int64 cyclesStart = 0, cyclesStop = 0;
unsigned __int64 nCtr = 0, nFreq = 0, nCtrStop = 0;
if(!QueryPerformanceFrequency((LARGE_INTEGER *) &nFreq)) return 0;
QueryPerformanceCounter((LARGE_INTEGER *) &nCtrStop);
nCtrStop += nFreq;
_asm
{
RdTSC
mov DWORD PTR cyclesStart, eax
mov DWORD PTR [cyclesStart + 4], edx
}
do{
QueryPerformanceCounter((LARGE_INTEGER *) &nCtr);
}while (nCtr < nCtrStop);
_asm
{
RdTSC
mov DWORD PTR cyclesStop, eax
mov DWORD PTR [cyclesStop + 4], edx
}
return ((float)cyclesStop-(float)cyclesStart) / 1000000;
}
Credits
- I got the assembler some time ago from an assembler newsgroup
- ...and credits to all programmers out there who share their knowing!
My name is Thomas, I'm born on January the 11th in
1970, right now I'm working in the Quality department
of a big Pipe mill as a Technician.
My hobbies are my girl friend, my car, RC-Planes and
Computers. I begun with VC++ some time ago and now
Programming is like a drug to me (I'm still a
beginner). I want to learn it all in a blink of an
eye
but i know that this is not possible. It's
real fun for me and I do small Programms for my own
use.
O.K. enough written..... I need my Time to debug
everything that crosses my way!