CPUz 之类的程序非常擅长提供有关系统的深度信息(总线速度、内存时序等)
但是,是否有一种编程方法可以计算每个内核(以及每个处理器,在每个 CPU 具有多个内核的多处理器系统中)频率,而无需处理 CPU 特定信息。
我正在尝试开发一种反作弊工具(用于时钟有限的基准测试竞赛),它能够在系统中所有事件内核(跨所有处理器)的基准测试运行期间记录 CPU 时钟。
最佳答案
我将在这里扩展我的评论。这对我来说太大而深入,无法放入评论中。
您尝试做的事情非常困难 - 由于以下原因而变得不切实际:
rdtsc
不是 由于 SpeedStep 和 Turbo Boost 等效果,始终提供正确的频率。 没有获得处理器频率的可移植方法:
获取 CPU 频率的“简单”方法是调用
rdtsc
两次,中间有固定的持续时间。然后除以差异将为您提供频率。问题是
rdtsc
没有给出处理器的真实频率。因为游戏等实时应用依赖于它,rdtsc
需要通过 CPU 节流和 Turbo Boost 保持一致。所以一旦你的系统启动,rdtsc
将始终以相同的速率运行(除非你开始用 SetFSB 或其他东西来弄乱总线速度)。例如,在我的 Core i7 2600K 上,
rdtsc
将始终在 3.4 GHz
处显示频率.但实际上,它在1.6 GHz
处闲置和时钟高达 4.6 GHz
通过超频 Turbo Boost 倍频器在负载下 46x
.但是,一旦找到测量真实频率的方法(或者您对
rdtsc
感到满意),您就可以使用 thread-affinities 轻松获得每个内核的频率。 .获取真实频率:
要获得处理器的真实频率,您需要访问 MSR(特定于模型的寄存器)或硬件性能计数器。
这些是内核级指令,因此需要使用驱动程序。如果您出于分发目的在 Windows 中尝试此操作,则您需要通过正确的驱动程序签名协议(protocol)。此外,代码会因处理器品牌和型号而异,因此您需要为每一代处理器提供不同的检测代码。
一旦到了这个阶段,有多种方法可以读取频率。
在 Intel 处理器上,硬件计数器可让您计算原始 CPU 周期。结合精确测量实时的方法(下一节),您可以计算出真实频率。通过 MSR,您可以访问其他信息,例如 CPU 倍频器。
所有已知的频率测量方法都需要准确的时间测量:
这也许是更大的问题。您需要一个计时器才能测量频率。有能力的黑客将能够篡改您可以在 C/C++ 中使用的所有时钟。
这包括以下所有内容:
clock()
gettimeofday()
QueryPerformanceCounter()
这份 list 不胜枚举。换句话说,您不能相信任何计时器,因为有能力的黑客将能够欺骗所有计时器。例如
clock()
和 gettimeofday()
可以通过直接在操作系统内更改系统时钟来欺骗。糊涂QueryPerformanceCounter()
更难。获得真正的时间测量:
上面列出的所有时钟都很脆弱,因为它们通常以某种方式从同一个系统基本时钟派生而来。并且该系统基本时钟通常与系统基本时钟相关联 - 可以在系统启动后通过超频实用程序进行更改。
因此,获得可靠且防篡改的时间测量的唯一方法是读取外部时钟,例如 HPET或 ACPI .不幸的是,这些似乎也需要内核级访问。
总结:
构建任何类型的防篡改基准几乎肯定需要编写内核模式驱动程序,该驱动程序需要为 Windows 进行证书签名。对于随意的基准测试作者来说,这通常是太多的负担。
这导致了防篡改基准的短缺,这可能是近年来竞争性超频社区整体衰落的原因之一。
关于c++ - 找出 CPU 时钟频率(每个内核、每个处理器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8351944/