21

I just bought a nifty MBA 13" Core i7. I'm told the CPU speed varies automatically, and pretty wildly, too. I'd really like to be able to monitor this with a simple app.

Are there any Cocoa or C calls to find the current clock speed, without actually affecting it?

Edit: I'm OK with answers using Terminal calls, as well as programmatic.

Thanks!

Tim
  • 14,447
  • 6
  • 40
  • 63
  • Not being particularly familiar with osx, but wouldn't there be a /proc type file system with that information? e.g. on Linux it's /proc/cpuinfo – Marc B Mar 30 '12 at 19:25
  • There's no `/proc/` as far as I can tell. There's a `system_profiler` command which gives the CPU speed listed on the box, but it doesn't change with the live updating clock speed – Tim Mar 30 '12 at 19:29
  • See [this question](http://stackoverflow.com/questions/8351944/finding-out-the-cpu-clock-frequency-per-core-per-processor) for why this is extremely difficult to do. – Mysticial Mar 30 '12 at 19:50
  • 1
    Reading through now. If it helps at all, I don't care about cheaters - since I won't be trying to cheat myself. It's more of a curiosity tool. – Tim Mar 30 '12 at 19:55
  • 1
    Mystical, I'm about to put a bounty on this question. Again, I don't need it to be cheat-proof - I just want to watch TurboBoost kick in (maybe write an app to play [this video](http://www.youtube.com/watch?v=qcDztfFXPww) every time it does) – Tim Apr 02 '12 at 16:56

5 Answers5

15

You can query the CPU speed easily via sysctl, either by command line:

sysctl hw.cpufrequency

Or via 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;
}
DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • 4
    Unfortunately, this seems to return the "box advertised" speed (now 2.3ghz on my MBPR) but not the SpeedStep adjusted speed. – Tim Jan 16 '13 at 23:22
  • However, this is a useful and easy insight into the use of sysctl, so thank you for that! – Tim Jan 16 '13 at 23:23
  • Does not give current, but advertised speed. hw.cpufrequency, hw.cpufrequency_min, hw.cpufrequency_max all give the same. – mist Apr 18 '14 at 09:36
  • 1
    This code will overflow the Hz on the new generation of > 4Ghz processors. Need to use this instead. sysctlbyname("hw.cpufrequency_max", &speed, &len, NULL, 0); to support a 64-bit value for the frequency. – Ken Aspeslagh Mar 10 '15 at 13:38
  • hmm `sysctl hw.cpufrequency` always reports 2500000000 for me. The Intel Power Gadgetreports varying "IA" values from 1.3Ghz to 3.4GHz, wonder if there's a way to get more up to date values... – rogerdpack Dec 20 '16 at 20:22
  • 2
    This does not work on my M1 MacBook – user5359531 Jan 26 '23 at 17:24
  • 1
    It seems that this entry is indeed missing for ARM-based systems. I guess that's due to their big.LITTLE CPU design (performance + efficiency cores), a common CPU frequency does not exist. The performance cores and efficiency cores run at different frequencies and both can scale their performance. – DarkDust Jan 27 '23 at 07:47
13

Try this tool called "Intel Power Gadget". It displays IA frequency and IA power in real time.

http://software.intel.com/sites/default/files/article/184535/intel-power-gadget-2.zip

Doug
  • 794
  • 7
  • 12
Yevgeni
  • 208
  • 2
  • 7
  • 1
    This is really exactly what I wanted. It even includes sample objective-c... Perfect! – Tim Apr 10 '13 at 14:13
8

Since it's an Intel processor, you could always use RDTSC. That's an assembler instruction that returns the current cycle counter — a 64bit counter that increments every cycle. It'd be a little approximate but e.g.

#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;
}

Output 'Clocks per second: 2002120630' on my 2Ghz MacBook Pro.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • On my MBA, it shows 1.8ghz, which is exactly right, but is there any way to force the i7 into turbo boost? – Tim Mar 30 '12 at 19:42
  • 7
    `rdtsc` is not a reliable way to measure a processor's clock speed. It does not adjust itself to turbo-boost/CPU-throttling (among other things). – Mysticial Mar 30 '12 at 19:48
  • @Mysticial on the contrary; it's usually advised as being an unreliable way to measure a CPU's clock speed _exactly because_ it is affected by turbo boost and CPU throttling. – Tommy Mar 30 '12 at 20:08
  • 1
    @Tommy My tests suggests other wise. On my Xeon at stock 3.2 GHz `rdtsc` always says 3.2 GHz regardless of what I set the multiplier to (2.4, 2.6, 2.8, 3.0, 3.2 GHz... all get reported as 3.2 GHz by `rdtsc`) `rdtsc` seems to change only when you start messing with the bus speeds. – Mysticial Mar 30 '12 at 20:11
  • Is there a way to determine what the multiplier is? I'm interested in both knowing what speedstep pulls the CPU down to at idle and where TurboBoost puts the CPU under load. – Tim Mar 30 '12 at 20:20
  • @Tim, I think you have to access the BIOS to get bus-speed/multiplier information. There's no easy way to do that since there are hundreds of different motherboard/BIOS/CPU systems... – Mysticial Mar 30 '12 at 20:23
  • @Mystical I've seen some apps around which claim to find the information about current core speed, including Intel's own app (on Windows), but no source code anywhere. I'm sure there's a way to do it - Intel has a [big ole' pdf with sample code](http://www.intel.com/content/dam/www/public/us/en/documents/application-notes/processor-identification-cpuid-instruction-note.pdf) but I can't get it to compile - though I'll continue trying. – Tim Mar 30 '12 at 20:43
0

There is a kernel extension written by "flAked" which logs the cpu p-state to the kernel log. http://www.insanelymac.com/forum/index.php?showtopic=258612

maybe you could contact him for the code.

nurbs999
  • 87
  • 10
0

This seems to work correctly on OSX. However, it doesn't work on Linux, where sysctl is deprecated and KERN_CLOCKRATE is undefined.

#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);
tbh
  • 1
  • Running `sysctl kern.clockrate` at command line gives me a steady `kern.clockrate: { hz = 100, tick = 10000, tickadj = 2, profhz = 100, stathz = 100 }` where the Intel CPU profiler is showing varying values, so I don't think this works with the speedstep adjustments. – Tim May 01 '13 at 03:00