I’ve been experimenting with power capping using Intel RAPL limits on my Framework with the i5 1135 running Ubuntu 22.04 since I wasn’t happy with the CPU getting to 90C and the fan running very loud when I start a multi-core workload - let’s say multithreaded compiling.
https://www.kernel.org/doc/html/latest/power/powercap/powercap.html
I stopped thermald to prevent it from changing the RAPL settings. Then I ran some tests with multi-core and single-core benchmarks and tweaked the limits to get a balance I like (using the pts/c-ray and pts/encode-flac benchmarks in phoronix-test-suite).
I ended up with the settings:
Long term power limit: 14 watts / 10 seconds
Short term power limit: leave default (unlimited)
Peak power limit: 36 watts
On the multi-threaded benchmark, this lets the CPU boost all cores to 3.2GHz for a short period of time, then settles around 2.7-2.8GHz, and never gets much above 60C.
On the single-threaded benchmark, it still lets the CPU maintain max boost on one core at a time - around 4.0GHz on my CPU - and that one core stays around 70C.
Your mileage may vary, so I’d recommend running some tests if you want to try this. The limits could be lower if you want more battery life.
$ sudo systemctl stop thermald
$ sudo powercap-set intel-rapl --zone=0 --constraint=0 -l 14000000 -s 10000000
$ sudo powercap-set intel-rapl --zone=0 --constraint=2 -l 36000000
(The units are microwatts / microseconds so multiply by 1,000,000. On this CPU, Zone 0 is the CPU package, Constraint 0 is the long term limit, Constraint 2 is the peak limit. Constraint 1 is the short term limit, it’s set to a high value by default. I didn’t see much difference setting either the peak or short term limit, the short term limit has a very small time window by default.)
I wrote a systemd unit file to apply the settings at startup. I also wrote one for a battery saver mode with 10w/20w limits but haven’t tested it much yet.
/etc/systemd/system/intel-rapl-balanced.service
[Unit]
Description=Set Intel RAPL power limits (balanced)
Conflicts=intel-rapl-powersave.service thermald.service
[Service]
ExecStart=/bin/sh -c "powercap-set intel-rapl -z 0 -c 0 -l 14000000 -s 10000000 && powercap-set intel-rapl -z 0 -c 2 -l 36000000"
ExecStop=/bin/sh -c "powercap-set intel-rapl -z 0 -c 0 -l 200000000 && powercap-set intel-rapl -z 0 -c 2 -l 121000000"
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
/etc/systemd/system/intel-rapl-powersave.service
[Unit]
Description=Set Intel RAPL power limits (powersave)
Conflicts=intel-rapl-balanced.service thermald.service
[Service]
ExecStart=/bin/sh -c "powercap-set intel-rapl -z 0 -c 0 -l 10000000 -s 10000000 && powercap-set intel-rapl -z 0 -c 2 -l 20000000"
ExecStop=/bin/sh -c "powercap-set intel-rapl -z 0 -c 0 -l 200000000 && powercap-set intel-rapl -z 0 -c 2 -l 121000000"
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable intel-rapl-balanced
$ sudo systemctl start intel-rapl-balanced
$ sudo systemctl disable thermald
(Since I put Conflict directives, starting one will automatically stop the other and thermald.)