Test 6 – Foreground Work with All 16 CPUs Busy
The previous experiment leaves some CPU capacity available.
I want one more demanding test where every CPU is already under pressure.
I start 16 low-priority workers:
cd ~/m2-scheduler-tests
sudo -v
sudo perf sched record -a \
-o foreground-16.data \
-- sleep 75 \
> foreground-16-perf-record.txt 2>&1 &
FOREGROUND16_PERF_PID=$!
sudo turbostat --quiet \
--interval 1 \
--num_iterations 75 \
--show 'CPU,Core,Busy%,Avg_MHz,Bzy_MHz,CPU%c1,CPU%c6,CoreTmp,PkgWatt' \
> foreground-16-turbostat.txt 2>&1 &
FOREGROUND16_TURBO_PID=$!
sleep 2
nice -n 19 stress-ng \
--cpu 16 \
--cpu-method matrixprod \
--timeout 65s \
--metrics-brief \
> background-16.txt 2>&1 &
BACKGROUND16_PID=$!
sleep 5
openssl speed \
-seconds 50 \
-bytes 16384 \
sha256 \
2>&1 | tee foreground-16-openssl.txt
wait "$BACKGROUND16_PID"
wait "$FOREGROUND16_PERF_PID"
wait "$FOREGROUND16_TURBO_PID"
sudo perf sched timehist \
-i foreground-16.data \
--no-call-graph \
-M -V \
> foreground-16-sched.txt
grep -E 'openssl|stress-ng-cpu' \
foreground-16-sched.txt \
> foreground-16-workloads-sched.txt
Timing note: This run did not use OpenSSL’s -elapsed option. OpenSSL therefore calculated its reported throughput using process CPU time rather than wall-clock time. As the foreground process was repeatedly descheduled, I also calculate its effective wall-clock throughput from the completed operation count and scheduler trace.
This test confirms that niceness affects CPU-time allocation once every CPU is occupied. However, Linux still did not give the foreground thread stable access to a P-core.
Foreground OpenSSL Result
| Measurement | Result |
|---|---|
| Wall-clock duration | 50.003 seconds |
| CPU time received | 46.601 seconds |
| CPU availability | 93.20% |
| P-core time | 13.620 seconds (29.23%) |
| E-core time | 22.722 seconds (48.76%) |
| LP E-core time | 10.258 seconds (22.01%) |
| CPU migrations | 827 |
| Average scheduling delay | 1.132 ms |
| 95th-percentile scheduling delay | 2.174 ms |
| 99th-percentile scheduling delay | 3.000 ms |
| Maximum scheduling delay | 4.000 ms |
| OpenSSL-reported throughput | 3.099 GB/s |
| Effective wall-clock throughput | 2.883 GB/s |
Unlike the previous test, OpenSSL was not confined to LP E-cores. It received slightly more P-core time and slightly less LP E-core time than their respective 25% shares of the processor. Nevertheless, it moved continuously across all 16 CPUs and never settled on a particular core class.
The foreground thread migrated 827 times, or approximately 16.5 times per second. Its 29.23% P-core residency indicates a modest preference for the faster cores, but almost 71% of its execution still occurred on E-cores or LP E-cores.
OpenSSL Timing
OpenSSL completed 8,799,429 SHA-256 operations and reported:
3.099 GB/s
Without the -elapsed option, openssl speed measured 46.52 seconds of process CPU time. The scheduler trace recorded 46.601 seconds of CPU runtime over a wall-clock duration of 50.003 seconds.
The reported 3.099 GB/s therefore represents throughput while OpenSSL was scheduled on a CPU. It does not include the periods during which the foreground process was waiting to run.
Using the completed operation count and the 50.003-second wall-clock duration gives an effective throughput of 2.883 GB/s. This is 24.8% below the isolated scheduler result of 3.833 GB/s, 25.2% below the pinned P-core baseline and 0.7% below the preceding LP E-core foreground test.
The scheduler trace makes it possible to calculate the effective result accurately. To make OpenSSL report wall-clock throughput directly, a repeated version of this test should include -elapsed:
openssl speed -elapsed -seconds 50 -bytes 16384 sha256
Background Workload
| Measurement | Result |
|---|---|
| Total background CPU time | 993.099 CPU-seconds |
| CPU time during overlap | 753.316 CPU-seconds |
| Average CPUs received during overlap | 15.07 |
| CPU migrations | 10,558 |
| Bogo ops/s | 36,424.55 |
| Change from isolated 16-worker test | −4.47% |
Before OpenSSL started, the 16 background workers received approximately 15.96 CPUs. During the overlap, this fell to 15.07 CPUs. OpenSSL received the remaining 0.93 CPU.
The foreground workload therefore displaced almost exactly one CPU’s worth of low-priority work. The background workers lost 46.90 CPU-seconds across the complete run, closely matching OpenSSL’s 46.60 CPU-seconds.
Background throughput fell from 38,128.52 to 36,424.55 bogo operations per second. This 4.47% reduction corresponds closely to the CPU time transferred to OpenSSL. Performance per background CPU-second was effectively unchanged.
Migration Behaviour
The introduction of the ordinary-priority thread caused substantially more scheduler activity.
| Workload | CPU migrations |
|---|---|
| OpenSSL | 827 |
| Background workers | 10,558 |
| Earlier isolated 16-worker workload | 42 |
The foreground thread moved steadily throughout the test rather than only during startup. Despite this activity, background performance per CPU-second did not decline. The migrations therefore produced no obvious additional throughput penalty beyond the CPU time transferred to OpenSSL.
Frequency, Power and Temperature
| Measurement during overlap | Result |
|---|---|
| CPU busy | 99.77% |
| Average busy frequency | 3,235 MHz |
| P-core busy frequency | 3,828 MHz |
| E-core busy frequency | 3,102 MHz |
| LP E-core busy frequency | 2,909 MHz |
| Average package power | 54.43 W |
| Maximum temperature | 91°C |
The run again shows the sustained power transition observed during the isolated 16-worker test.
| Full-load period | Busy frequency | Package power |
|---|---|---|
| Initial turbo period | 3,359 MHz | 58.51 W |
| Sustained period | 2,938 MHz | 44.63 W |
The transition occurred approximately 35 seconds after OpenSSL started, or around 40 seconds after the background load began. This is consistent with the processor leaving its short-term turbo power window and settling near its sustained package power limit.
Interpretation
When spare LP E-core capacity existed, Linux protected total throughput by placing OpenSSL entirely on an LP E-core and leaving the low-priority background workers undisturbed.
Once every CPU was occupied, normal priority did take effect. OpenSSL displaced approximately one CPU’s worth of background execution and maintained low millisecond-scale scheduling delays. In that respect, the scheduler honoured the foreground task’s higher priority.
Core selection remained disappointing. OpenSSL received only a modest preference for P-cores, migrated 827 times and achieved effective wall-clock performance slightly below the preceding LP E-core result. Linux respected priority when distributing CPU time, but it did not give the higher-priority saturated thread stable access to the processor’s highest-capacity cores.
Next page: Page 9 – Conclusions
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.