找出CPU时钟频率(每个核心,每个处理器)

kid*_*man 36 c++ cpu cpu-speed

像CPUz这样的程序非常擅长提供有关系统的深度信息(总线速度,内存时序等)

但是,是否有一种编程方式来计算每个核心(以及每个处理器,在每个CPU具有多个核心的多处理器系统中)频率,而无需处理CPU特定信息.

我正在尝试开发一种反作弊工具(用于时钟限制基准测试),它能够在基准测试期间记录系统中所有活动核心(所有处理器)的CPU时钟.

Mys*_*ial 31

我会在这里扩展我的评论.这对我来说太大了,不适合评论.

你要做的事情非常困难 - 由于以下原因导致不切实际:

  • 没有可移植的方式来获得处理器频率.rdtsc不要总是给正确的频率,由于效果,如SpeedStep技术和Turbo Boost.
  • 所有已知的测量频率的方法都需要精确的时间测量.但是,确定的骗子可以篡改系统中的所有时钟和计时器.
  • 准确地以防篡改的方式读取处理器频率和时间将需要内核级访问.这意味着Windows的驱动程序签名.

没有可移植的方式来获得处理器频率:

获得CPU频率的"简单"方法是rdtsc在两者之间调用固定的持续时间.然后除去差异将给你频率.

问题是rdtsc没有给出处理器的真实频率.由于游戏等实时应用程序依赖于它,因此rdtsc需要通过CPU限制和Turbo Boost保持一致.因此,一旦系统启动,rdtsc将始终以相同的速率运行(除非您开始使用SetFSB或其他东西弄乱总线速度).

例如,在我的Core i7 2600K上,rdtsc将始终显示频率3.4 GHz.但实际上,它通过超频的Turbo Boost乘法器闲置1.6 GHz并且时钟4.6 GHz负载不足46x.

但是一旦你找到了衡量真实频率的方法,(或者你很开心rdtsc),你可以使用线程亲和力轻松获得每个核心的频率.

获得真正的频率:

要获得处理器的真实频率,您需要访问MSR(特定于型号的寄存器)或硬件性能计数器.

这些是内核级指令,因此需要使用驱动程序.如果您在Windows中尝试进行此分发,则需要通过正确的驱动程序签名协议.此外,代码因处理器品牌和型号而异,因此每个处理器代需要不同的检测代码.

一旦进入这个阶段,有多种方法可以读取频率.

在Intel处理器上,硬件计数器可让您计算原始CPU周期.结合精确测量实时的方法(下一节),您可以计算真实频率.MSR使您可以访问其他信息,例如CPU倍频器.


所有已知的测量频率的方法都需要准确测量时间:

这可能是更大的问题.您需要一个计时器才能测量频率.一个有能力的黑客将能够篡改您可以在C/C++中使用的所有时钟.这包括以下所有内容:

  • clock()
  • gettimeofday()
  • QueryPerformanceCounter()
  • 等等...

这个清单一直在继续.换句话说,你不能相信任何计时器,因为一个有能力的黑客将能够欺骗所有这些计时器.例如clock(),gettimeofday()可以通过直接在OS中更改系统时钟来欺骗.愚弄QueryPerformanceCounter()更难.

获得真正的时间测量:

上面列出的所有时钟都是易受攻击的,因为它们通常以某种方式从相同的系统基本时钟导出.并且该系统基本时钟通常与系统基准时钟相关联 - 在系统已经通过超频实用程序启动后可以更改.

因此,获得可靠且防篡改的时间测量的唯一方法是读取外部时钟,例如HPETACPI.不幸的是,这些似乎也需要内核级访问.


总结一下:

构建任何类型的防篡改基准测试几乎肯定需要编写内核模式驱动程序,这需要Windows的证书签名.对于休闲基准编写者来说,这通常是一种负担.

这导致了防篡改基准的短缺,这可能导致近年来竞争激烈的超频社区整体下滑.

  • 我接受这个作为答案,因为这使我的期望正确.我希望Frank没有给他的CPU-z SDK定价如此之高.或者为这种用法提供价格较低的版本.1000欧元对于我来说对于免费基准测试来说太过分了. (2认同)