【发布时间】:2013-07-20 09:26:50
【问题描述】:
我正在尝试制作一个 C# 软件来读取有关 CPU 的信息并将其显示给用户(就像 CPU-Z 一样)。 我目前的问题是找不到显示CPU频率的方法。
起初我尝试了使用 Win32_Processor 类的简单方法。事实证明它非常有效,除非 CPU 超频(或超频)。
然后,我发现我的注册表在 HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 包含 CPU 的“标准”时钟(即使超频)。问题在于,在现代 CPU 中,当 CPU 不需要其全功率时,Core Multiplier 会降低,因此 CPU 频率也在变化,但注册表中的值保持不变。
我的下一步是尝试使用 RdTSC 来实际计算 CPU 频率。我为此使用了 C++,因为如果该方法有效,我可以将它嵌入到 C# 项目中。我在http://www.codeproject.com/Articles/7340/Get-the-Processor-Speed-in-two-simple-ways 找到了下一个代码 但问题是一样的:程序只给了我最大频率(就像在注册表值中,1-2 Mhz 的差异),而且它看起来也比它应该加载的 CPU 更多(我什至有 CPU 负载峰值)。
#include "stdafx.h"
#include <windows.h>
#include <cstdlib>
#include "intrin.h"
#include <WinError.h>
#include <winnt.h>
float ProcSpeedCalc() {
#define RdTSC __asm _emit 0x0f __asm _emit 0x31
// variables for the clock-cycles:
__int64 cyclesStart = 0, cyclesStop = 0;
// variables for the High-Res Preformance Counter:
unsigned __int64 nCtr = 0, nFreq = 0, nCtrStop = 0;
// retrieve performance-counter frequency per second:
if(!QueryPerformanceFrequency((LARGE_INTEGER *) &nFreq))
return 0;
// retrieve the current value of the performance counter:
QueryPerformanceCounter((LARGE_INTEGER *) &nCtrStop);
// add the frequency to the counter-value:
nCtrStop += nFreq;
_asm
{// retrieve the clock-cycles for the start value:
RdTSC
mov DWORD PTR cyclesStart, eax
mov DWORD PTR [cyclesStart + 4], edx
}
do{
// retrieve the value of the performance counter
// until 1 sec has gone by:
QueryPerformanceCounter((LARGE_INTEGER *) &nCtr);
}while (nCtr < nCtrStop);
_asm
{// retrieve again the clock-cycles after 1 sec. has gone by:
RdTSC
mov DWORD PTR cyclesStop, eax
mov DWORD PTR [cyclesStop + 4], edx
}
// stop-start is speed in Hz divided by 1,000,000 is speed in MHz
return ((float)cyclesStop-(float)cyclesStart) / 1000000;
}
int _tmain(int argc, _TCHAR* argv[])
{
while(true)
{
printf("CPU frequency = %f\n",ProcSpeedCalc());
Sleep(1000);
}
return 0;
}
我还应该提到,我已经在 AMD CPU 上测试了最后一种方法。 我还为 RdTSC 方法尝试了一些其他代码,但没有一个能正常工作。
最后,我试图理解用于制作这个程序的代码https://code.google.com/p/open-hardware-monitor/source/browse/,但它对我来说太复杂了。
所以,我的问题是:如何使用 C++ 或 C# 实时确定 CPU 频率(即使 CPU 超频)?我知道这个问题被问了很多次,但没有人真正回答我的问题。
【问题讨论】:
-
海森堡在 87 年前就预言,你无法做到这一点。只需确保您不需要此问题的答案即可。
-
@Hans:我确信所需的精度不会给 Heisenberg 带来问题。
-
我给出了一个答案,它展示了如何使用 C/C++ 做到这一点,即使对于超频的系统也是如此。
标签: c# c++ visual-c++