[推薦]使用一簡單的類別去計算CPU的頻率 |
|
axsoft
版主 發表:681 回覆:1056 積分:969 註冊:2002-03-13 發送簡訊給我 |
資料來源:http://www.codeproject.com/system/cputest.asp
範例下載:
1.source file: http://www.codeproject.com/system/CPUTest/CPUTest_src.zip
2. Demo Project File : http://www.codeproject.com/system/CPUTest/CPUTest_demo.zip
IntroductionCPUTest 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. 時間就是金錢 << 發問前請先找找舊文章 >> 發表人 - axsoft 於 2002/07/16 10:24:42 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |