How to switch cpu governor on battery power?

I’m having a hard time finding anything that configures the cpu governor to be performance when connected to power and powersave otherwise. Is this possible?

In fact, it should be more subtle: only use performance when the battery is > than, say, 15% and the power supply is actually strong enough to support it.

Furthermore, a GUI tool to quickly switch while compiling on the go would be great. Is there really nothing like this?

1 Like

I tried my hand at packaging the only gui I could find cpupower-gui. PR: cpupower-gui: init at 0.8.0 by jonringer · Pull Request #94676 · NixOS/nixpkgs · GitHub

Problem is that it needs a systemd service running in the background, and I lost interest in packaging it further :).

1 Like

I think TLP can change the governor but maybe not at some battery percent. Processor — TLP 1.6 documentation

On a similar note I would love a tool to dim the screen backlight when on battery. I got an way with acpid but it’s not perfect.

I also wonder if there’s tools for systemd timers while on battery. To fetch my emails a bit less often and things like that.

I have made very good experiences with TLP. It can be nicely configured through nix.

services.tlp.extraConfig = ''
  CPU_SCALING_GOVERNOR_ON_AC=performance
  CPU_SCALING_GOVERNOR_ON_BAT=powersave
  CPU_MAX_PERF_ON_AC=100
  CPU_MAX_PERF_ON_BAT=30
'';

As you can see it also clocks down my CPU by 70% when on battery. The performance is still good enough for me and the battery will last more than 8h.

6 Likes

services.tlp.extraConfig has been deprecated in recent nixpkgs versions.

Here is my configuration using the new syntax:

  services.tlp = {
    enable = true;
    settings = {
      CPU_SCALING_GOVERNOR_ON_BAT="powersave";
      CPU_SCALING_GOVERNOR_ON_AC="powersave";

      # The following prevents the battery from charging fully to
      # preserve lifetime. Run `tlp fullcharge` to temporarily force
      # full charge.
      # https://linrunner.de/tlp/faq/battery.html#how-to-choose-good-battery-charge-thresholds
      START_CHARGE_THRESH_BAT0=40;
      STOP_CHARGE_THRESH_BAT0=50;

      # 100 being the maximum, limit the speed of my CPU to reduce
      # heat and increase battery usage:
      CPU_MAX_PERF_ON_AC=75;
      CPU_MAX_PERF_ON_BAT=60;
    };
  };
7 Likes

I have a dumb question.

If I slow down my CPU while on battery, won’t tasks take longer and end up draining about the same amount of power?

2 Likes

I’m not sure how it works for CPUs. In real life, I’m usually less tired when I walk 1km compared to running the same distance even though it takes me longer :-).

1 Like

As far as I understand the power consumption of your CPU doesn’t scale linearly with the clock rate. In other words, the CPU is more efficient if clocked down.

But I think this isn’t even the deciding factor here.
The CPU is not fully utilized most of the times. That means, if you allow the CPU to go into a higher power state, it will not only be faster, but also burn more energy doing nothing. Even if you have your governor on powersafe, your CPU will not immediately clock down when it is not used. There is always some margin.

Also there are always a bunch of useless background programs which you don’t really need but always use CPU cycles (At least after you open a few browser tabs). These background tasks often eat enough CPU cycles for the governor to decide to clock your CPU high, even it’s not really required.

And what benefit does it bring to you if the invisible animated ad banner on your browser tab 999 runs with 5 or 10 frames per second in the background?

The only really safe and consistent method to prevent this unnecessary drain of energy, is to configure an upper limit for your performance.

It’s true that your computer will be slower, but since most of your CPU time usually goes into stuff you don’t even notice, the resulting loss of time this isn’t nearly as high as the lost battery time which is the alternative.

2 Likes

Actually many distribution use powersave no matter if on battery power or not: Processor — TLP 1.6 documentation