- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试制作一个 C# 软件来读取有关 CPU 的信息并将它们显示给用户(就像 CPU-Z)。我目前的问题是我找不到显示 CPU 频率的方法。
起初我尝试使用 Win32_Processor 类 的简单方法。事实证明它非常有效,除非 CPU 超频(或降频)。
然后,我发现我的注册表在 HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 处包含 CPU 的“标准”时钟(即使已超频)。问题在于,在现代 CPU 中,当 CPU 不需要全功率时,核心倍频会降低,因此 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 超频时)?我知道这个问题被问了很多次,但实际上没有人回答我的问题。
最佳答案
是的,该代码会等待整整一秒钟,这会导致该核心 100% 忙一秒钟。一秒钟的时间足以让动态时钟算法检测负载并将 CPU 频率从节能状态中踢出。如果具有升压功能的处理器实际显示的频率高于标记频率,我不会感到惊讶。
不过,这个概念还不错。您需要做的是 sleep 大约一秒钟的时间间隔。然后,不是假设 RDTSC 调用恰好相隔一秒,而是除以 QueryPerformanceCounter
指示的实际时间。
此外,我建议在调用 QueryPerformanceCounter
之前和之后检查 RDTSC
,以检测 RDTSC
和 QueryPerformanceCounter
这会弄乱你的结果。
不幸的是,新处理器上的 RDTSC
实际上并不计算 CPU 时钟周期。因此,这并不反射(reflect)动态变化的 CPU 时钟速率(不过,它确实在没有忙等待的情况下测量标称速率,因此它是对问题中提供的代码的重大改进)。
所以看起来您毕竟需要访问特定于模型的寄存器。哪个can't be done from user-mode . The OpenHardwareMonitor project有一个可以使用的驱动程序和code for the frequency calculations
float ProcSpeedCalc()
{
/*
RdTSC:
It's the Pentium instruction "ReaD Time Stamp Counter". It measures the
number of clock cycles that have passed since the processor was reset, as a
64-bit number. That's what the <CODE>_emit</CODE> lines do.
*/
// Microsoft inline assembler knows the rdtsc instruction. No need for emit.
// variables for the CPU cycle counter (unknown rate):
__int64 tscBefore, tscAfter, tscCheck;
// variables for the Performance Counter 9steady known rate):
LARGE_INTEGER hpetFreq, hpetBefore, hpetAfter;
// retrieve performance-counter frequency per second:
if (!QueryPerformanceFrequency(&hpetFreq)) return 0;
int retryLimit = 10;
do {
// read CPU cycle count
_asm
{
rdtsc
mov DWORD PTR tscBefore, eax
mov DWORD PTR [tscBefore + 4], edx
}
// retrieve the current value of the performance counter:
QueryPerformanceCounter(&hpetBefore);
// read CPU cycle count again, to detect context switch
_asm
{
rdtsc
mov DWORD PTR tscCheck, eax
mov DWORD PTR [tscCheck + 4], edx
}
} while ((tscCheck - tscBefore) > 800 && (--retryLimit) > 0);
Sleep(1000);
do {
// read CPU cycle count
_asm
{
rdtsc
mov DWORD PTR tscAfter, eax
mov DWORD PTR [tscAfter + 4], edx
}
// retrieve the current value of the performance counter:
QueryPerformanceCounter(&hpetAfter);
// read CPU cycle count again, to detect context switch
_asm
{
rdtsc
mov DWORD PTR tscCheck, eax
mov DWORD PTR [tscCheck + 4], edx
}
} while ((tscCheck - tscAfter) > 800 && (--retryLimit) > 0);
// stop-start is speed in Hz divided by 1,000,000 is speed in MHz
return (double)(tscAfter - tscBefore) / (double)(hpetAfter.QuadPart - hpetBefore.QuadPart) * (double)hpetFreq.QuadPart / 1.0e6;
}
大多数编译器都提供了一个 __rdtsc()
内在函数,在这种情况下,您可以使用 tscBefore = __rdtsc();
而不是 __asm
block .不幸的是,这两种方法都是特定于平台和编译器的。
关于c# - 在获得 CPU 频率方面需要一些帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17774118/
我有这个问题: 我们声称对 float 使用相等测试是不安全的,因为算术运算会引入舍入错误,这意味着两个应该相等的数字实际上并不相等。 对于这个程序,您应该选择一个数字 N,并编写一个程序来显示 1
为什么这个脚本的输出是 5 而不是 8 ? 我认为 -- 意味着 -1 两次。 var x = 0; var y = 10; while ( x
我现在可以从 cmd 窗口中执行的 FFmpeg 过程中读取最后一行。 使用脚本主机模型对象引用此源。 Private Sub Command1_Click() Dim oExec
使用 vlookup,当匹配发生时,我想从匹配发生的同一行显示工作表 2 中 C 列的值。我想出的公式从 C 列表 2 中获取值,但它从公式粘贴在表 3 上的行中获取,而不是从匹配发生的位置获取。 这
我在破译 WCF 跟踪文件时遇到了问题,我希望有人能帮助我确定管道中的哪个位置发生了延迟。 “Processing Message XX”的跟踪如下所示,在事件边界和传输到“Process Actio
我有四个表,USER、CONTACT、CONACT_TYPE 和 USER_CONTACT USER_CONTACT 存储用户具有填充虚拟数据的表的所有联系人如下 用户表 USER_ID(int)|
以下有什么作用? public static function find_by_sql($sql="") { global $database; $result_set = $data
我正在解决 JavaBat 问题并且对我的逻辑感到困惑。 这是任务: Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat,
我正在研究一些 Scala 代码,发现这种方法让我感到困惑。在匹配语句中,sublist@ 是什么?构造?它包含什么样的值(value)?当我打印它时,它与 tail 没有区别,但如果我用尾部替换它,
我正在使用以下代码自行缩放图像。代码很好,图像缩放也没有问题。 UIImage *originImg = img; size = newSize; if (originImg.size.width >
Instruments 无法在我的 iPad 和 iPhone 上启动。两者都已正确配置,我可以毫无问题地从 xcode 调试它们上的代码,但 Instruments 无法启动。 我听到的只是一声嘟嘟
我想用 iPhone 的 NSRegularExpression 类解析此文本: Uploaded652.81 GB 用于摘录上传和652.81文本。 最佳答案 虽然我确实认为 xml 解析器更适合解
我找到了 solution在 Stackoverflow 上,根据过滤器显示 HTML“li”元素(请参阅附件)。本质上基于 HTML 元素中定义的 css 类,它填充您可以从中选择的下拉列表。 我想
这是一个简单的问题,但我是在 SQL 2005 中形成 XML 的新手,但是用于形成如下所示表中的 XML 的最佳 FOR XML SQL 语句是什么? Column1 Column2 -
我在 www.enigmafest.com 有一个网站!您可以尝试打开它!我面临的问题是,在预加载器完成后,主页会出现,但其他菜单仍然需要很长时间才能加载,而且声音也至少需要 5 分钟! :( 我怎样
好吧,我正在尝试用 Haskell 来理解 IO,我想我应该编写一个处理网页的简短小应用程序来完成它。我被绊倒的代码片段是(向 bobince 表示歉意,但公平地说,我并不想在这里解析 HTML,只是
如何使用背景页面来突出显示网站上的某个关键字,无论网站是什么(谷歌浏览器扩展)?没有弹出窗口或任何东西,它只是在某人正在查看的网站上编辑关键字。我以前见过这样的,就是不明白怎么做!谢谢你的帮助。 最佳
我是 Javascript 新手,需要一些帮助。 先看图片: . 积分预测器应用程序。 基本上当用户通过单选按钮选择获胜团队时它应该在积分栏中为获胜队添加 10 分,并且并根据得分高的球队自动对表格进
这是我的情况 - 我要发送一份时事通讯,我试图做的是,当用户单击电子邮件中的链接时,它会重定向到我的网页,然后会弹出一个灯箱,显示视频。我无法在页面加载时触发灯箱,因为您可以在查看灯箱之前转到同一页面
我有这个代码。 ¿Cuanto es ? Ir 我想获取用户输入的“验证码”值。我尝试这个但行不通。有什么帮助吗? var campo = d
我是一名优秀的程序员,十分优秀!