如何在OS X操作系统中编程检测当前的CPU时钟速度?

21

我刚购买了一个很棒的MBA 13英寸i7处理器。我被告知CPU速度会自动变化,而且相当不稳定。我非常想用一个简单的应用程序来监控它。

有没有Cocoa或C调用可以查找当前的时钟速度,而不会实际影响它?

编辑:我接受使用终端调用和编程的答案。

谢谢!


我不是特别熟悉OSX,但是否有一个文件系统类似于/proc来存储这些信息呢?例如,在Linux上,它就是/proc/cpuinfo。 - Marc B
据我所知,似乎没有 /proc/。有一个 system_profiler 命令,它可以提供盒子上列出的 CPU 速度,但它不会随着实时更新的时钟速度而改变。 - Tim
请参考这个问题,了解为什么这是非常困难的。 - Mysticial
1
正在阅读。如果有帮助的话,我不在乎作弊者——因为我自己也不会尝试作弊。这更像是一个好奇心工具。 - Tim
1
神秘的是,我即将在这个问题上设置赏金。再次强调,我不需要它具有防作弊功能 - 我只想看到TurboBoost启动(也许编写一个应用程序,在每次启动时播放此视频)。 - Tim
5个回答

15
您可以轻松地通过sysctl查询CPU速度,可以通过命令行进行操作:
sysctl hw.cpufrequency

或通过 C 语言:

#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int main() {
        int mib[2];
        unsigned int freq;
        size_t len;

        mib[0] = CTL_HW;
        mib[1] = HW_CPU_FREQ;
        len = sizeof(freq);
        sysctl(mib, 2, &freq, &len, NULL, 0);

        printf("%u\n", freq);

        return 0;
}

4
不幸的是,这似乎返回了“宣传的”速度(现在是我MBPR上的2.3GHz),但没有返回SpeedStep调整后的速度。 - Tim
然而,这是一个有用且易于理解sysctl使用的见解,因此感谢您! - Tim
1
这段代码将会在新一代 > 4Ghz 处理器上导致 Hz 溢出。需要改用以下代码: sysctlbyname("hw.cpufrequency_max", &speed, &len, NULL, 0); 来支持64位频率值。 - Ken Aspeslagh
2
这在我的 M1 MacBook 上不起作用。 - user5359531
1
看起来这个条目确实在基于ARM的系统中缺失了。我猜这是由于他们的big.LITTLE CPU设计(性能+效率核心),不存在常见的CPU频率。性能核心和效率核心运行在不同的频率上,两者都可以调整其性能。 - DarkDust
显示剩余2条评论

13

1
这真的是我想要的。它甚至包括了Objective-C的示例...太完美了! - Tim

8

由于这是英特尔处理器,您可以使用RDTSC指令。它是一个汇编指令,返回当前循环计数器-一个每个周期增加的64位计数器。它可能有些粗略,但可以用。

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>

uint64_t rdtsc(void)
{
    uint32_t ret0[2];
    __asm__ __volatile__("rdtsc" : "=a"(ret0[0]), "=d"(ret0[1]));
    return ((uint64_t)ret0[1] << 32) | ret0[0];
}

int main(int argc, const char * argv[])
{
    uint64_t startCount = rdtsc();
    sleep(1);
    uint64_t endCount = rdtsc();

    printf("Clocks per second: %llu", endCount - startCount);

    return 0;
}

在我的2Ghz MacBook Pro上输出“每秒时钟数:2002120630”。


在我的MBA上,它显示1.8ghz,这完全正确,但有没有办法强制i7进入Turbo Boost模式? - Tim
7
rdtsc 不是衡量处理器时钟速度可靠的方法。它无法调整以适应 Turbo Boost/CPU 节流等因素。 - Mysticial
1
@Tommy 我的测试结果表明不同。在我的3.2 GHz的Xeon机子上,无论我将倍频设置为多少(2.4, 2.6, 2.8, 3.0, 3.2 GHz...),rdtsc总是会报告3.2 GHz。只有当你开始操纵总线速度时,rdtsc才会发生变化。 - Mysticial
@Tim,我认为你需要访问BIOS以获取总线速度/倍频信息。由于有数百种不同的主板/BIOS/CPU系统,因此没有简单的方法可以做到这一点... - Mysticial
@Mystical 我看到一些应用程序声称可以找到有关当前核心速度的信息,包括英特尔自己的应用程序(在Windows上),但没有任何源代码。我相信有一种方法可以做到这一点 - 英特尔有一个大而全的pdf文件,其中包含示例代码,但我无法编译它 - 尽管我将继续尝试。 - Tim
显示剩余2条评论

0

0

在OSX上似乎可以正常工作。 然而,在Linux上无法工作,因为sysctl已被弃用且KERN_CLOCKRATE未定义。

#include <sys/sysctl.h>
#include <sys/time.h>

  int mib[2];
  size_t len;
  mib[0] = CTL_KERN;
  mib[1] = KERN_CLOCKRATE;
  struct clockinfo clockinfo;
  len = sizeof(clockinfo);
  int result = sysctl(mib, 2, &clockinfo, &len, NULL, 0);
  assert(result != -1);
  log_trace("clockinfo.hz: %d\n", clockinfo.hz);
  log_trace("clockinfo.tick: %d\n", clockinfo.tick);

在命令行运行 sysctl kern.clockrate,我会得到一个稳定的输出 kern.clockrate: { hz = 100, tick = 10000, tickadj = 2, profhz = 100, stathz = 100 }。而 Intel CPU 分析器显示的数值不同,因此我认为这不适用于 speedstep 调整。 - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接