Detect current CPU Clock Speed Programmatically on OS X?
Asked Answered
C

5

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!

Conk answered 30/3, 2012 at 19:2 Comment(5)
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/cpuinfoLurlinelusa
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 speedConk
See this question for why this is extremely difficult to do.Snapdragon
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.Conk
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 every time it does)Conk
U
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

Undirected answered 9/4, 2013 at 14:7 Comment(1)
This is really exactly what I wanted. It even includes sample objective-c... Perfect!Conk
O
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;
}
Olwena answered 16/1, 2013 at 10:2 Comment(7)
Unfortunately, this seems to return the "box advertised" speed (now 2.3ghz on my MBPR) but not the SpeedStep adjusted speed.Conk
However, this is a useful and easy insight into the use of sysctl, so thank you for that!Conk
Does not give current, but advertised speed. hw.cpufrequency, hw.cpufrequency_min, hw.cpufrequency_max all give the same.Pragmaticism
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.La
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...Haydenhaydn
This does not work on my M1 MacBookDonofrio
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.Olwena
U
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

Undirected answered 9/4, 2013 at 14:7 Comment(1)
This is really exactly what I wanted. It even includes sample objective-c... Perfect!Conk
P
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.

Pianola answered 30/3, 2012 at 19:36 Comment(7)
On my MBA, it shows 1.8ghz, which is exactly right, but is there any way to force the i7 into turbo boost?Conk
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).Snapdragon
@Snapdragon 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.Pianola
@Pianola 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.Snapdragon
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.Conk
@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...Snapdragon
@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 but I can't get it to compile - though I'll continue trying.Conk
U
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.

Unanimous answered 7/8, 2012 at 13:9 Comment(0)
F
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);
Frailty answered 1/5, 2013 at 2:44 Comment(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.Conk

© 2022 - 2024 — McMap. All rights reserved.