Last Week on My Mac: CPU %

Say what you like about Apple, but it gives us the best software instrumentation. If you’re a developer, the instruments provided in Xcode are second to none, and for users Activity Monitor and its supporting command tools give deep insights into all manner of performance problems. In the transition to Apple Silicon, Activity Monitor’s CPU History window is almost the only way of observing how macOS users the two different cores in M1 chips. Although M1 Macs have already taken great strides, this is still the transition, and Activity Monitor has further to travel, particularly in measuring the workload on the M1’s CPU cores.

Intel models have been pretty straightforward to deal with: having just one type of core, what’s shown as CPU % appears to be the total active residency for all the cores. This only becomes confusing in two respects, that being a sum of two or more percentages, it invariably totals to a maximum of 200% or more, and hyperthreading can double that.

Apple Silicon is different, in that it has two types of core, which are used differently according to the performance (QoS) set for each thread, and core frequencies vary dynamically between 600 MHz and a maximum of just over 2 (E cores) or 3 (P cores) GHz. As I’ve explained, ignoring the latter can give a misleading view of how fully occupied cores are. Figures given for CPU % , the most widely used measurement in Activity Monitor’s CPU view, need improvement if they’re going to continue to be useful on Apple Silicon Macs.


Most users appear comfortable with a scale of 0-100%, but it’s hard to see why this should be a floating point number rather than an integer. Even one place after the decimal point pretends a level of precision which is neither possible nor appropriate, and has no value for the user anyway. Trying to distinguish between 12.1% and 12.2% simply isn’t appropriate.

Single-scale or multiple

What does confuse many users is totalling the percentage across all cores in the CPU, so that full scale on an eight-core chip is 800%, or 1600% when fully hyperthreaded. This has the unfortunate side-effect of amplifying values obtained from CPUs with more cores. Irrespective of the number of cores available, users tend to get twitchy when CPU % rises much about 10%. When CPU % is expressed as the sum across all cores, a process which is taking a mere 2% on each of eight cores has that figure magnified to 16% if full scale is 800%. Expressing CPU % as a true percentage, with a full scale of 100%, is surely preferable.


Simply giving the active residency, or any equivalent measure, without knowing the frequency of that core cluster is extremely misleading. I’ve already given some examples of this in practice.

Run a couple of low-QoS threads on the two E cores of an M1 Pro and you might see test performance of 180 Mloops/s with active residency of close to 100% on each core. To see similar test performance on the four E cores of an original M1 you’re likely to see close to 100% on each core again, but that multiplies up to a total of around 400%. That’s because the M1 Pro’s two E cores are running at their maximum frequency of 2064 MHz, while the four in the original M1 chip are held at less than half of that, 972 MHz. The best way to accommodate changing frequency, and the different maximum frequencies of E and P cores, is to set the full-scale 100% value at the maximum frequency of that core type.

Currently the only way in which core cluster frequency can be measured is using the command tool powermetrics, which provides detailed information about a great deal more, but is out of reach of the great majority of users. It would be even better if Activity Monitor were able to display set frequency for each cluster of cores individually.

Core types

Watching the CPU History window of an M1 Mac quickly impresses you of the highly asymmetric workloads occurring in normal use. The great majority of macOS services are run almost exclusively on the E cores, while most apps and other user tasks are run on the P cores. Depending on the nature of the process(es) a user is investigating, they may need to know active residency for either or both types of core. Currently, these are only available in powermetrics.

Expressing separate values for CPU % on the two core types not only solves that problem, but avoids having to weight results to produce an arbitrary overall figure covering both types, and differences in future core designs.

Proposed metric

On Apple Silicon Macs, the current CPU % figures for processes and overall should be replaced by two simple integer-valued percentages for E and P cores separately, each calculated according to
( Σ(% active residency of core) / (number of cores) ) x ( (set core frequency) / (maximum core frequency) )

For example, on an M1 Pro’s two E cores running a process at an active residency of 80% on each, at a frequency of 2064 MHz:
(80 + 80)/2 x (2064/2064) = 80%
compared with an M1’s four E cores running a process at an active residency of 80% on each, at a frequency of 972 MHz:
(80 + 80 + 80 + 80)/4 x (972/2064) = 38%
which compare with the current overall CPU % shown in Activity Monitor, assuming negligible P core load, of 160% (max 800%) and 320% (max 1000%) respectively.