Monitoring CPU Frequency and Activity
I use turbostat to monitor per-CPU activity, operating frequency and idle-state residency.
First, I check which counters are available on the M2.
sudo turbostat --list | tee turbostat-fields.txt
All the fields I’m interested in are available:
CPUCoreBusy%Avg_MHzBzy_MHzCPU%c1CPU%c6CoreTmpPkgWatt
I then run an unpinned, sustained single-threaded SHA-256 workload. Omitting taskset allows the Linux scheduler to decide which CPU should execute it.
sudo turbostat \
--quiet \
--show 'CPU,Core,Busy%,Avg_MHz,Bzy_MHz,CPU%c1,CPU%c6,CoreTmp,PkgWatt' \
--out single-thread-turbostat.txt \
-- openssl speed -seconds 120 -bytes 16384 sha256 \
2>&1 | tee single-thread-openssl.txt
The -bytes 16384 option limits the benchmark to the 16 KiB block size used for the earlier core comparison. In this command mode, turbostat reports aggregate figures covering the complete OpenSSL run.
The active CPU produced the following figures:
| CPU | Core type | Average frequency | Busy | Frequency while busy | C1 residency | C6 residency | Temp |
|---|---|---|---|---|---|---|---|
| 2 | P-core | 4,183 MHz | 99.65% | 4,198 MHz | 0.00% | 0.00% | 60°C |
CPU 2 is one of the processor’s four P-cores. It was busy for 99.65% of the test, with an average operating frequency of 4,183 MHz and an average busy frequency of 4,198 MHz. The small difference between Avg_MHz and Bzy_MHz is expected because the CPU was executing instructions almost continuously. Its C1 and C6 residency figures were consequently both 0.00%.
No other CPU exceeded 10% utilisation during the run, so turbostat did not reveal any substantial execution away from CPU 2. The scheduler trace in the next test provides a more precise record of migrations.
OpenSSL reported SHA-256 throughput of 3.849 GB/s. This is only 0.13% below the 3.854 GB/s average obtained when the benchmark was explicitly pinned to a P-core. Together, the performance and turbostat results show that Linux correctly selected a P-core for this sustained single-threaded workload and kept it there for essentially the entire test.
Busy% shows how heavily each CPU was used, whereas Bzy_MHz reports its average frequency only while it was executing instructions. This distinction becomes particularly useful with bursty workloads that repeatedly alternate between working and sleeping.
Next page: Page 3 – Sustained Single-Thread Scheduling
Pages in this article:
Page 1 – Introduction
Page 2 – Monitoring CPU Frequency and Activity
Page 3 – Sustained Single-Thread Scheduling
Page 4 – Bursty Single-Thread Scheduling
Page 5 – Scaling from 1 to 16 CPU Workers
Page 6 – Real-World Multithreaded Scheduling with FFmpeg
Page 7 – Foreground Work Against 12 Low-Priority Workers
Page 8 – Foreground Work with All 16 CPUs Busy
Page 9 – Conclusions
Complete list of articles in this series:
| MINISFORUM M2 Core Ultra 7 356H Mini PC | |
|---|---|
| Introduction | Introduction to the series and interrogation of the machine |
| NPU | Setting up and testing the NPU |
| Benchmarks | I run a series of benchmarks focusing on the CPU, GPU, Memory, and Disk performance |
| Power | Testing and comparing the power consumption |
| BIOS | In the world of computing, BIOS, which stands for Basic Input/Output System, plays a crucial role |
| Cores | A look at Intel’s hybrid architecture |
| Intel processors | P-Cores, E-Cores and LP E-Cores Compared Across 4 Intel Processors |
| NPU | NPU and Llama |
| Scheduling | Does Linux Schedule Panther Lake Correctly? |
| Next articles in the series will continue to focus on the machine's NPU | |

Please read our Comment Policy before commenting.