2012年(158)
分类: C/C++
2012-11-14 16:30:06
对于这篇文章本人快记不清是不是本人写的啦,如果不是本人写的,请告知本人,谢谢!即使是本人写的,也是根据Intel的源代码修改而来。
////// normal speed
#include
#include
void main( void )
{
unsigned long ProcSpeed = 0;
HKEY hKey;
LONG rt = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ,
&hKey);
if( ERROR_SUCCESS == rt )
{
unsigned long
buflen = sizeof( ProcSpeed );
RegQueryValueEx( hKey, "~MHz", NULL,
NULL, (LPBYTE)&ProcSpeed, &buflen );
RegCloseKey(hKey);
}
if( 0 != ProcSpeed )
printf( "%ldMHz\n", ProcSpeed );
else
printf( "查询失败\n", ProcSpeed );
}
////// raw speed
#include
#include
typedef unsigned long ulong;
// 高精度计时
inline unsigned __int64 GetCycleCount()
{
// __asm
RDTSC
__asm _emit 0x0F
__asm _emit 0x31
// return
EDX:EAX;
}
void main( void )
{
__int64 raw_freq = 0;
__int64
t0,t1;
__int64 freq =0; // Most current frequ.
calculation
__int64 freq2 =0; // 2nd most current frequ.
calc.
__int64 freq3 =0; // 3rd most current frequ.
calc.
__int64 total; // Sum of previous three frequency
calculations
__int64 tries=0; // Number of times a
calculation has
__int64 total_cycles=0, cycles; // Clock cycles elapsed during
test
__int64 stamp0=0, stamp1=0; // Time Stamp Variable for
beginning and end of test
__int64 total_ticks=0, ticks; //
Microseconds elapsed during test
__int64 count_freq; //
高精度计数器频率
#ifdef WIN32
int iPriority;
HANDLE hThread =
GetCurrentThread();
#endif
if( !QueryPerformanceFrequency( (PLARGE_INTEGER)&count_freq )
)
{
printf( "ERROR: The installed hardware does not support a
high-resolution performance counter\n" );
return;
}
do { // This do loop runs up to 20 times
or
// until the average of the
previous
// three calculated frequencies
is
// within 1 MHz of each of
the
// individual calculated
frequencies.
// This resampling increases
the
// accuracy of the results
since
// outside factors could affect
this
// calculation
tries++; // Increment number of times sampled on this call to
cpuspeed
freq3 = freq2; // Shift frequencies back to make room for
new frequency measurement
freq2 = freq; //
QueryPerformanceCounter( (PLARGE_INTEGER)&t0 );
t1 =
t0;
#ifdef WIN32
iPriority = GetThreadPriority(hThread);
if
( iPriority != THREAD_PRIORITY_ERROR_RETURN )
{
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
}
#endif
while( t1-t0 < 50 )
{
//
Loop until 50 ticks have
// passed since last
read of hi-
// res counter. This accounts
for
// overhead later.
QueryPerformanceCounter( (PLARGE_INTEGER)&t1
);
stamp0 = GetCycleCount();
}
t0 =
t1; // Reset Initial Time
while( t1-t0 < 1000 )
{
// Loop until 1000 ticks have
// passed since
last read of hi-
// res counter. This allows
for
// elapsed time for sampling.
QueryPerformanceCounter( (PLARGE_INTEGER)&t1
);
stamp1 = GetCycleCount();
}
#ifdef WIN32
// Reset priority
if ( iPriority !=
THREAD_PRIORITY_ERROR_RETURN )
{
SetThreadPriority(hThread, iPriority);
}
#endif // WIN32
cycles = stamp1 - stamp0;// Number of internal
// clock cycles is
// difference between
// two time stamp
// readings.
ticks = t1 -
t0;
// Number of external ticks
is
// difference between
two
// hi-res counter reads.
// Note that some seemingly arbitrary mulitplies and
//
divides are done below. This is to maintain a
// high level of
precision without truncating the
// most significant data.
According to what value
// ITERATIIONS is set to, these multiplies
and
// divides might need to be shifted for optimal
//
precision.
ticks = ticks * 100000;
// Convert
ticks to hundred
// thousandths of a
tick
ticks = ticks / ( count_freq/10 );
// Hundred Thousandths of a
// Ticks / ( 10 ticks/second
)
// = microseconds (us)
total_ticks += ticks;
total_cycles += cycles;
if( ticks%count_freq > count_freq/2 )
ticks++; // Round up if necessary
freq =
cycles/ticks; // Cycles / us =
MHz
if(
cycles%ticks > ticks/2 )
freq++; // Round up
if necessary
total = ( freq + freq2 + freq3
);
// Total last three frequency
// calculations
} while ( (tries < 3 ) ||
(tries <
20)&&
((abs(3 * freq -total) > 3
)||
(abs(3 * freq2-total) > 3 )||
(abs(3
* freq3-total) > 3 )));
// Compare last three
calculations to
// average of last three
calculations.
// Try one more significant digit.
freq3 = ( total_cycles * 10 ) /
total_ticks;
freq2 = ( total_cycles * 100 ) / total_ticks;
if ( freq2 - (freq3 * 10) >= 6 )
freq3++;
raw_freq = total_cycles / total_ticks;
printf( "%ldMHz\n",
raw_freq );
}