[TRACKING] Linux battery life tuning

Hey y’all! Lots of stream of consciousness info coming and too lazy to proofread :), so if something doesn’t make sense please feel free to ask me to clarify.

TLDR:

  • Setting an EPP value of 225 seems to be a nice battery/performance balance, but the Intel P-State driver allows you to set whatever you want from 0-255, so it’s customizable to your needs!
  • Setting a max GPU boost/frequency of 450MHz at first blush seems like a battery sweet spot, but same idea applies here. 100MHz to 1,300MHz. Set whatever fits your needs.
  • I’d currently advise against using power-profiles-daemon if you need anything between EEP values of 255 (power) (PPD power-saver) and 128 (balance_performance) (PPD balanced).

So I got a chance with the long weekend to spend some time diving back into battery life tuning, especially after reading reports of some people getting 8-10 hours of battery with light workloads.

Did a bunch of this and that, and from some short tests, I think it’s very possible now to achieve that. There’s definitely been some kernel improvements since I last did a thorough test back in Sept or whatever, but some things that I didn’t see mentioned, though tangentially touched upon (kudos to the all the effort in this thread!) which I think are gamechangers:

CPU Energy Performance Preference

https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_pstate.html#energy-vs-performance-hints
The Energy Performance Preference (EPP) “knob” is where the most energy savings will come from.

# NOTE: (fish shell allows me to use the `*` wildcard in `cpu*`to affect all cpu number directories
# I'm not sure how to do it succinctly in bash etc., though I know a for loop works
cat /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_available_preferences

As we all probably already know these are the values that can be set:

default performance balance_performance balance_power power

However, from the documentation (and I haven’t seen it mentioned anywhere else! Not TLP nor power-profiles-daemon documentation)

The values we can set can also be numeric (0-255) (most to least performance) (most to least energy use) and written like so (as detailed in the above intel_pstate link):

echo "225" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference

These 4 numbers when written translate like so:

Number EPP
0 performance
128 balance_performance
192 balance_power
255 power

Which translate roughly to these frequency limits:

EPP Number Notes
performance 0 boosts to ~4.0GHz, then stays at ~2.8Ghz. Supposed to boost up to 4.7GHz per specs I think? Eh, this is a thread about optimizing battery life, anyways.
balance_performance 128 boosts to ~3.8GHz, then stays at ~2.8GHz
balance_power 192 boosts to ~3.1GHz, then stays at ~2.8GHz
power 255 limits the CPU frequency to ~1.6GHz. This is noticeably laggy – good for reading, but not for compiling code/“multitasking” etc…

So we can see that there’s definitely some optimization to be had between the most energy efficient power mode (1.6GHz) and the next balance_power mode (2.8GHz).

Generally, more energy is used with higher clock speed, meaning an increase from 1.6GHz to 1.7GHz uses much less energy than 2.8GHz to 2.9GHz. This is why disabling Turbo on battery is likely a good idea. There’s also the argument of consumption between race-to-idle and pace-to-idle, but I’d say with rogue/energy-intensive JavaScript sites (even Reddit with autoplaying video), it’s probably a good idea to cut off the top-end frequency where energy consumption is very high.

I’ve found that setting an EPP value of 225 (between power (255) and balance_power (192)) will limit the frequency to ~2.3GHz. This is noticeably faster than 1.6GHz, less energy consuming than 2.8GHz, and seemingly enough for most tasks. At first blush, it seems optimal for my “on battery” needs. Web browsing/coding/working equates to ~= 5-7W roughly? I haven’t tested thoroughly yet, but will as I plan to work more on battery.

Of importance: power-profiles-daemon got rid of the balance_power mode for now:

So a user has to choose between the slow power mode and the higher energy demand balance_performance mode. Terrible for optimizing battery life.

I recompiled PPD to use power, balance_power, and balance_performance (@me if you want the patch), but ended up just switching to TLP. It doesn’t seem to be in the docs, but it’s possible to set any EPP value from 0-255 like so:

/etc/tlp.conf

# Set Intel CPU energy/performance policies HWP.EPP and EPB:
# performance, balance_performance, default, balance_power, power.
...
CPU_ENERGY_PERF_POLICY_ON_AC=balance_performance
CPU_ENERGY_PERF_POLICY_ON_BAT=225
### Note this value is numeric ^

Also, the same ideas apply to the GPU as well:
/etc/tlp.conf

# Set the min/max/turbo frequency for the Intel GPU.
...
INTEL_GPU_MIN_FREQ_ON_AC=100
INTEL_GPU_MIN_FREQ_ON_BAT=100
INTEL_GPU_MAX_FREQ_ON_AC=1300
INTEL_GPU_MAX_FREQ_ON_BAT=450
INTEL_GPU_BOOST_FREQ_ON_AC=1300
INTEL_GPU_BOOST_FREQ_ON_BAT=450

You can see how limiting GPU max/boost frequencies affect power usage/framerate/performance with this:
http://www.kevs3d.co.uk/dev/shaders/

But the above settings (I haven’t tested long-term yet) seem to have a large impact. With the Mountains (in the sunset) demo:

Limited to 1300MHz I saw usage go up to ~20W. FPS ~18.
Limited to 450MHz I saw usage go up to ~10W. FPS ~55.

Limiting the GPU doesn’t make sense if you need the graphics power, but for just web browsing/coding/etc., it can significantly limit bursts of unwanted battery drain, e.g from website videos/ads. It also may make sense for watching videos, though from what I’ve seen, the GPU already does a good job at clocking down.
Related sidenote: for 1080P video playback I was able to get down to 5.5W on 1% brightness, 75% speakers, wifi/bt on – that’s an actual 10 hours of playback! MPV/VAAPI HW decode. Round down to a solid 8 hours at higher brightness.

Miscellaneous

Specs:
i7-1165G7, 64GB G.Skill 3200Mhz, 2TB SK Hynix P31
Fedora 5.17.11-300.fc36.x86_64 with Sway 1.7
Seems like Sway uses slightly more battery than Gnome 4x, could just be my installation, though, and the tradeoff imo is worth it anyways.


Seeing the reports that Ubuntu 22.04 has low idle usage, I tested it out stock on my system. Idle was very low (down to ~2.4W), and mucking/browsing/clicking around with 1 or 2 tabs in Firefox was about 4-6W, roughly.


It’s been a while since I’ve daily driven Windows, but one can set EPP values there with ThrottleStop.


Lastly a nice tip for those that like to stream music in the background while working:

This plays a YouTube stream in the background with no-video. Uses very little energy – very-much-way-more-less than streaming in a browser, especially with the still :pensive: poor Linux browser VAAPI support.

yt-dlp -q -f 91 -o - "youtube video url, can even be a livestream" | mpv --no-cache --no-video -

I’m curious to see how 12th gen energy usage will compare to 11th gen at the same performance .


Cheers! :melting_face:

23 Likes