Power Profiles User Guide#
Overview#
Intel® Core™ Ultra edge nodes can be tuned to trade sustained performance
against heat, fan noise, and energy use. The Infrastructure Blueprint ships a
set of local power-tuning tools under tools/power-tuning/ that let you:
Apply a ready-made power profile (
LowPower…MaxPerformance).Set an explicit package (PkgWatt) and optional platform (SysWatt) cap.
Monitor live power and package temperature.
Stress the CPU and integrated GPU to validate a profile under load.
On the target system: the commands below use repository-relative paths (
tools/power-tuning/…), which work when you run them from the repo root. On a host provisioned with Infrastructure Blueprint, the same tools are available on the target system at/opt/edge/developer/tools/power-tuning/. Eithercd /opt/edge/developerand use the relative paths as written, or prefix each command with the full path (e.g.sudo /opt/edge/developer/tools/power-tuning/set_power_profile.sh --list).
All tuning is enforced through Intel RAPL (Running Average Power Limit) and the
Intel Low Power Mode daemon (intel_lpmd). These two layers behave differently
across a reboot:
The RAPL power cap (the PL1/PL2 wattage limits) is programmed into volatile CPU registers and reverts automatically on reboot to firmware defaults. This is the main enforcement and the built-in safety net.
The
intel_lpmdconfig file is written to disk, so it persists across a reboot and is re-read by the daemon on the next boot. To undo the daemon-side tuning you must restore the config (see What persists across a reboot).
Note: These tools are tuned for Intel Panther Lake (Core Ultra). On other Intel silicon they still run, but the Config-TDP (cTDP) levels and the platform (psys/SysWatt) domain may differ or be unavailable.
Prerequisites#
An Intel
x86_64host (Core Ultra / Panther Lake recommended).A CPU frequency governor can conflict with
intel_lpmd. Theperformanceandondemandgovernors override the daemon’s low-power intent, so either switch topowersave— which cooperates withintel_lpmd— or disable the governor service altogether:# Option 1: switch to the powersave governor echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor # Option 2: disable the governor service sudo systemctl disable --now powersave.service
Linux ships several competing power-management daemons. Stop and disable any that are running — for example
tlp,tuned,cpufreqd, orondemand— so they will conflict withintel_lpmdfor control of CPU power and frequency.BIOS settings that hand CPU power/frequency control to the OS. The power limits and EPP/EPB tuning only take effect when the OS (not firmware) owns these controls — verify them before applying a profile, or the script may succeed while the limits are silently ignored. Setting names and menu paths vary by vendor. See the BIOS Settings sections in
skills/set-power-profile/SKILL.mdfor the full mandatory list plus optional settings (e.g. disabling firmware DBPM, unlocking the power-limit MSRs, and Config Base Power / cTDP).sudoaccess. The power scripts read/write MSRs and restart a system service, so they re-run themselves withsudo.msrkernel module andmsr-tools(rdmsr/wrmsr) — required to read the cTDP levels and program the RAPL MSRs:sudo modprobe msr sudo apt-get install -y msr-tools
turbostatfor monitoring (from the matchinglinux-toolspackage):sudo apt-get install -y linux-tools-$(uname -r)
stress-ngfor load generation:sudo apt-get install -y stress-ng
Power Profiles#
A profile is a package-power (PkgWatt) budget plus a default burst ratio. The package cap is enforceable on every platform; on silicon that also exposes the psys (SysWatt) domain, a matching whole-platform cap is added automatically.
Note: The table below is a reference recommendation. The values can be overridden with command-line parameters (e.g.
--pkgWatt,--sysWatt,--burstRatio,--pl1Tau) for further tuning — see Set an Explicit Power Envelope.
Profile |
PkgWatt budget |
Default burst ratio |
Typical use |
|---|---|---|---|
|
10 W |
1.25 |
Fanless / battery, mostly idle (kiosk, signage, sensor) |
|
15 W |
1.25 |
Light interactive (basic UI, browsing) |
|
20 W |
1.18 |
Interactive / mixed workloads |
|
25 W |
1.19 |
Steady general compute |
|
platform max (cTDP Level 2) |
1.18 |
Sustained heavy compute (AI inference, transcode, builds) |
|
(none) |
(none) |
Explicit |
Terminology#
Term |
Meaning |
|---|---|
PkgWatt |
Package power — the CPU cores plus the integrated GPU. The main limit these tools set. |
SysWatt |
Platform power — the whole board (package plus memory, VRs, other rails). Exposed by the RAPL psys domain. Not available on all systems: many Core Ultra platforms do not expose a psys domain at all (any |
PL1 |
Power Limit 1 — the sustained power allowed over the long term. |
PL2 |
Power Limit 2 — the short burst power the chip may briefly reach. |
burst_ratio |
The multiplier that sets the burst limit (PL2) relative to the sustained limit (PL1): |
tau (PL1 tau) |
Time window (seconds) over which PL1 is averaged — how long a burst can last before settling to PL1. |
cTDP Level 2 |
Configurable TDP — the highest sustained power the silicon supports (the maximum you can request). |
Apply a Named Profile#
Use set_power_profile.sh with --profile. Run from the repository root.
On the target system, the tools are available at /opt/edge/developer/tools/power-tuning/ —
either cd /opt/edge/developer and use the relative paths as written, or prefix
each command with the full path (e.g.
sudo /opt/edge/developer/tools/power-tuning/set_power_profile.sh --profile LowPower):
# List the available profiles and their PkgWatt budgets
tools/power-tuning/set_power_profile.sh --list
# Longest battery / coolest, silent operation
sudo tools/power-tuning/set_power_profile.sh --profile LowPower
# Balanced interactive use
sudo tools/power-tuning/set_power_profile.sh --profile BalancedHigh
# Max sustained throughput (AI inference / transcode / builds)
sudo tools/power-tuning/set_power_profile.sh --profile MaxPerformance
# Override the default burst ratio for a snappier feel
sudo tools/power-tuning/set_power_profile.sh --profile Performance --burstRatio 1.4
# Profile PkgWatt with an explicit SysWatt cap (psys-capable platforms only)
sudo tools/power-tuning/set_power_profile.sh --profile Performance --sysWatt 35
# Preview only — resolve and print the plan without changing anything
tools/power-tuning/set_power_profile.sh --profile Performance --dry-run
--sysWattis not honored on every platform. The SysWatt cap only takes effect on silicon that exposes the RAPL psys domain. On platforms without it,--sysWattis silently ignored and only the PkgWatt cap is enforced; on platforms where the psys counter is present but frozen, the cap is written butturbostatstill reads a fixed value (SysWatt = 0.00, or any other constant that never changes with load). In both cases PkgWatt is the reliable effective figure. The--dry-runoutput reports whether psys is supported on this host.
Set an Explicit Power Envelope#
For fine-grained control, set the package (and optionally platform) watts directly instead of a named profile.
# Sustained 20 W with the default 1.25 burst ratio (PL2 = 25 W)
sudo tools/power-tuning/set_power_profile.sh --pkgWatt 20
# Strict cap — no burst (PL1 = PL2 = 30 W)
sudo tools/power-tuning/set_power_profile.sh --pkgWatt 30 --burstRatio 1.0
# Independent platform cap: PkgWatt 25 W, SysWatt 35 W
sudo tools/power-tuning/set_power_profile.sh --pkgWatt 25 --sysWatt 35
# Custom PL1 time window (tau) of 10 s
sudo tools/power-tuning/set_power_profile.sh --pkgWatt 15 --pl1Tau 10
Option |
Meaning |
|---|---|
|
Package PL1 (sustained) target. Clamped to |
|
psys/platform (SysWatt) cap. Applied only on platforms that expose the psys domain; ignored otherwise. Default: same as PkgWatt. |
|
Burst ratio ( |
|
PL1 time window in seconds (default |
|
Resolve and print the plan without applying anything. |
|
List available profiles and exit. |
Monitor Power and Temperature#
Note:
pt_mon.shis provided as a reference monitor. You can use it, or any other power-monitoring tool you prefer (e.g.turbostat,powertop,intel_gpu_top, a BMC/OEM utility, or reading/sys/class/powercap/intel-rapl*). The power profile and stress steps are independent of which monitor you choose.
Watch package temperature and the RAPL power domains live with pt_mon.sh
(wraps turbostat). It samples every 2 s and tees to pt_mon.txt:
cd tools/power-tuning
sudo ./pt_mon.sh
For a custom interval, duration, or log path, run turbostat directly with the
same columns:
sudo turbostat -S --interval 1 --num_iterations 60 \
--show PkgTmp,PkgWatt,CorWatt,GFXWatt,RAMWatt,SysWatt \
| tee pt_mon.txt
Column |
Meaning |
|---|---|
|
CPU package temperature (°C). |
|
Whole-package power (cores + iGPU + uncore) — the most reliable effective figure. |
|
CPU cores portion of the package. |
|
Integrated GPU (graphics) portion. |
|
DRAM/memory RAPL domain. |
|
Platform (psys) power; reads |
Stress the Platform Under Load#
Note:
stress_gen.shprovides a simulated load for evaluation purposes. You can use it, or run the actual workload you want to evaluate — apply the power profile, start the monitor, and drive the platform with either the simulated stress below or your real application. The monitor reacts the same way to either.
Validate a profile or cap under real load with stress_gen.sh (wraps
stress-ng). No sudo needed — it runs as the current user:
# All CPUs at 100% + 12 iGPU workers, until Ctrl-C
tools/power-tuning/stress_gen.sh
# 4 CPU workers at 80%, no GPU load, for 2 minutes
tools/power-tuning/stress_gen.sh --cpus 4 --load 80 --gpu 0 --duration 2m
# CPU + iGPU burn-in for 5 minutes
tools/power-tuning/stress_gen.sh --gpu 8 --duration 5m
Option |
Meaning |
|---|---|
|
Number of CPU workers, |
|
Per-CPU load percentage, |
|
Number of stress-ng iGPU worker processes (default |
|
Run time in stress-ng syntax ( |
Stop a running stress test with Ctrl-C, or:
sudo pkill -x stress-ng
Real AI inference load with openvino_stress.sh#
For a load that resembles a production edge workload rather than a synthetic one,
openvino_stress.sh drives the CPU, GPU, or NPU with OpenVINO benchmark_app
running in a container (K3s pod or Docker, auto-detected). This is useful for
measuring throughput-per-watt and for thermal qualification with a real
neural-network compute pattern:
# 120 s of CPU inference load
tools/power-tuning/openvino_stress.sh --device cpu --duration 120
# 5 min of GPU inference load
tools/power-tuning/openvino_stress.sh --device gpu --duration 300
# NPU inference for a fixed number of iterations
tools/power-tuning/openvino_stress.sh --device npu --niter 500000
# Stop and remove any running benchmark containers/pods
tools/power-tuning/openvino_stress.sh --cleanup
Option |
Meaning |
|---|---|
|
Target accelerator (default |
|
Container runtime (default: auto-detect). |
|
Iteration count; |
|
Run time in seconds when |
|
Inference API mode (default |
|
Stop and remove running benchmark containers/pods. |
The default model is downloaded automatically on first run; override the model,
image, or thread count with --model, --image, and --nthreads.
Recommended Workflow#
To validate a power profile end to end, use three terminals:
Apply the profile:
sudo tools/power-tuning/set_power_profile.sh --profile Performance
Monitor power and temperature:
cd tools/power-tuning && sudo ./pt_mon.sh
Stress the platform and watch the monitor react:
tools/power-tuning/stress_gen.sh --duration 3m
stress_gen.shis a simulated load; substitute the real workload you want to evaluate here if you prefer — for example a real AI inference load withtools/power-tuning/openvino_stress.sh --device gpu --duration 3m.
Step up one profile at a time until throughput stops improving or the package temperature approaches the throttle point.
Side Effects and Tips#
Thermals & acoustics: higher profiles raise package temperature and fan noise; lower profiles run cooler and quieter (or fanless).
Throttling: if cooling can’t keep up, the firmware clamps sustained power below the target. The script reports the effective (enforced) value and notes when firmware clamped PL1.
SysWatt = 0.00: on some Core Ultra silicon the psys counter is frozen. The cap is still written, but turbostat can’t observe it — use PkgWatt as the effective figure. This is a firmware limitation, not a failure.Brief management gap: applying a profile restarts
intel_lpmd.service(~2 s) during which the daemon isn’t actively managing CPU states.Partial revert on reboot: the RAPL power cap resets to firmware defaults on reboot, but the
intel_lpmdconfig on disk does not — see below.
What Persists Across a Reboot#
The script changes two independent things with different lifetimes:
What changes |
Where it lives |
Reverts on reboot? |
|---|---|---|
RAPL cap (PL1/PL2 watts) |
Volatile CPU RAPL MSRs ( |
Yes — firmware re-initializes these on every boot. |
|
|
No — the file stays on disk and |
So on reboot intel_lpmd re-uses the config file the script wrote (assuming
intel_lpmd.service is enabled at boot); the daemon-side tuning is not undone by
a reboot — only the wattage cap is.
To restore the stock daemon behavior, put the original config back. The script
saves a one-time .orig backup of any model-specific file it overrides (e.g.
intel_lpmd_config_F6_M204.xml on Panther Lake):
sudo cp -a /usr/local/etc/intel_lpmd/intel_lpmd_config_F6_M204.xml.orig \
/usr/local/etc/intel_lpmd/intel_lpmd_config_F6_M204.xml
sudo systemctl restart intel_lpmd.service
Note: Only overridden model-specific files get an
.origbackup. The genericintel_lpmd_config.xmlthe script writes has no backup if no config existed there before.
Reference#
Power Profile Developer Guide — every MSR, powercap sysfs node, config file and service
set_power_profile.shtouches, with the reason for each access and how to restore it.Thermal Profile Developer Guide — the same inventory for
set_thermal_profile.sh.