CPUTest






4.78/5 (19投票s)
一个简单的类,用于计算 CPU 频率(MHz)
引言
CPUTest 只是一个包含几个 static
成员函数的简单类 (CCPU
)。它计算 CPU 的频率,用时 50 毫秒。
工作原理
这个想法很简单,并且已经被多次实现。所有现代处理器 (Pentium+) 都有一个时间戳计数器 (TSC),它每时钟周期递增一次。读取 TSC,延迟一段时间,再次读取 TSC,并获得两个时间戳的差值 (结果以时钟周期为单位)。将周期数除以延迟时间,即可得到频率。
令人惊艳之处
大多数获取 CPU MHz 的实现都使用 Sleep()
进行延迟。Sleep()
的问题在于它的精度不高,尤其是在用于小延迟时。为了获得合理的结果,你必须至少延迟 1000 毫秒。
为了克服这个问题,我使用了 QueryPerformanceFrequency()
和 QueryPerformanceCounter()
函数。
请查看这个函数,它是 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) }
这个延迟函数即使对于较短的时间段也相当准确。
此外,还有一个 _DelayOverhead()
函数,它被 GetMHz()
(见下文) 使用来计算调用此函数的开销,并将其从结果中减去。
此外,GetMHz()
(见下文) 函数能够更改进程优先级类和线程优先级,以便结果更准确。完成操作后,它会将 PC 和 TP 恢复到以前的设置。
由于以上所有原因,只需调用一次 GetMHz()
即可获得 CPU 的 MHz,并且完成时间仅需 50 毫秒!
// int mhz = CCPU::GetMHz(); //
CCPU 类函数
只有一个类,即 CCPU
类。它只包含 static
成员函数,不包含任何数据。
功能包括
// 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);
结论
希望这段代码对您有所帮助;希望它能正常工作;-)。
另外,如果您运行演示程序,请在此处发布您的 CPU 频率和您获得的结果,尤其是在结果完全错误的情况下。