48

I'd like to set the CPU frequency scaling governor for all cores at once instead of doing it individually for each core. Is there a way to do this?

(I know it would be easy to echo the governor to /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor, but I'm not looking for a custom solution.)

3
  • 2
    With "custom solution" you mean that a shell script is unacceptable, it needs to be a built-in GUI button? Jan 6, 2011 at 16:09
  • 1
    I'm just wondering if there already exists a solution in a standard installation (doesn't need to have a GUI).
    – htorque
    Jan 6, 2011 at 16:20
  • Check this page: idebian.wordpress.com/2008/06/22/cpu-frequency-scaling-in-linux under "debian implementation": It is apparently possible to change the boot default, and there is a userspace tool called powernowd. (This is a comment rather than reply because the post is from 2008, and I haven't tested if it still works...) Jan 6, 2011 at 22:47

8 Answers 8

29

I googled a lot and I think it's just not possible, so I added the following one-liner to my .bashrc:

function setgov ()
{
    echo "$1" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 
}

Now I can run something like setgov ondemand and all cores will switch to the ondemand governor.

2
  • 2
    This doesn't work as the file scaling_governor is owned by root and has restricted permissions. Changing the permissions is not always recommended.
    – Sri
    Sep 11, 2014 at 9:16
  • Please see alternative script in my comment to user49449's answer.
    – Sri
    Sep 11, 2014 at 9:53
28

I'm still a linux noob but don't you think cpufrequtils lets u do it by using (its not bundled in the Ubuntu OS but is there in the repository)

sudo apt-get install cpufrequtils
sudo cpufreq-set -r -g performance
  • The -r flag is used to set the change for all ("all hardware related") cores
5
  • 10
    The -r related option doesn't do it for all the cores. We have to specify the cpu number with option -c <number> however this script will do it for all cpus in one go: for ((i=0;i<$(nproc);i++)); do cpufreq-set -c $i -r -g performance; done
    – Sri
    Sep 11, 2014 at 9:50
  • 7
    Exactly, @Sri is right. cpufreq-set in fact lacks of ultimately simple but needed functionality. Lots of people as this vote counters clearly shows are just not aware of it because its description is simply misleading to top it off.
    – poige
    Oct 27, 2015 at 16:43
  • 5
    Who gives these +1's without testing???? This does not work at all. I posted the simplest working solution I could find.
    – switch87
    Dec 1, 2016 at 12:51
  • 4
    Broken: Only sets governor for first core, according to cpufreq-info
    – kidmose
    Jan 14, 2020 at 12:23
  • @kidmose finding is indeed correct.
    – Slbox
    Nov 2, 2021 at 21:41
12

the shortest command to change governor of all cores is the following:

sudo bash -c 'for ((i=0;i<$(nproc);i++)); do cpufreq-set -c $i -g performance; done'

You could add it to .bashrc like htorque mentioned setgov performance:

function setgov ()
{
     for i in {0..7}; 
     do 
         sudo  cpufreq-set -c $i -g $1; # run cpufreq-set with root
     done
}
2
  • You'll likely have more than 8 cores, so modify the "0..7" accordingly.
    – Raven
    Dec 10, 2019 at 20:30
  • You CANNOT run a bash function with sudo. You can instead stick that into /usr/local/bin/setgov, and even set it as setuid so you can run it without root privileges.
    – sleblanc
    Apr 9, 2020 at 15:57
9

You can do this for all cores at once by running

sudo cpupower frequency-set --governor performance
3
  • not available in 18.04 it seems Feb 15, 2020 at 12:20
  • The cpupower command is available on 18.04 with the appropriate linux-tools package for the running kernel, according to user299889
    – Zanna
    Dec 3, 2020 at 17:16
  • i can confirm that cpupower is only available after installing the "appropiate" linux-tools
    – Fuseteam
    Aug 13, 2023 at 20:42
3

Might as well add bash code completion, while we're at it:

function setgovernor () {
    echo "$1" | sudo tee 
    /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 
}
complete -W "$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)" setgovernor
2

Basing on switch87's answer, I made a simple script cpufreq-set-all, which will allow to do other cpufreq-set things with all CPUs:

   #!/bin/bash
   MAX_CPU=$((`nproc --all` - 1))
   for i in $(seq 0 $MAX_CPU); do
       echo "Changing CPU " $i " with parameter "$@;
       cpufreq-set -c $i $@ ;
   done

Now it can be invoked(after chmod +x, of course) like this:

cpufreq-set-all -g powersave

or

cpufreq-set-all -f 800Mhz
2

The way I set this to stick since the governor defaults back to powersave after about 30 seconds now as of Ubuntu 16.04 or more recent (I'm on Ubuntu Mate);

  1. Put this (one line of) code (thank you, courtesy of switch87 in the previous answer)

    sleep 60 && bash -c 'for i in {0..7}; do cpufreq-set -c $i -g performance; done'
    
  2. into the file in the directory

    /etc/rc.local
    

Mine is a line above "exit 0" and uncommented, under the commented ones.

"rc.local" for those who do not know, it runs the command as sudo. Any command it seems, to change the governor, needs to be run as sudo.

It lets the governor reset back to powersave and runs the code as sudo after 60 seconds to change it back to performance.

Change the "60" (in the code you copy) to whatever time (in seconds. 60 = 60 seconds= 1 minute) you need to delay the command and "performance" (in the command part) to what governor you want it to change to.

Out of my hours and hours of searching I have not found a more permanent fix for this than this. I figure what's a couple of minutes that it's on powersave if this is the best fix I've found, right? Right.

Not the best fix, but it makes it somewhat permanent after it does it's little switch to powersave thing. If you want to boot right up and jump into a game or something you're going to have to wait a minute for the code you just put in to switch it back from powersave or lower the timing on it (depending on how long it takes everything to start up so it'll switch back to performance correctly).

And, as always, to revert back to default (I've seen some issues with people's PCs overheating which is why they might have defaulted it to powersave in the first place) just remove the code from rc.local and reboot or switch it back manually with your cpu icon indicator switcher or run;

 sudo /etc/init.d/cpufrequtils restart

in the terminal and or reboot.

1

sometimes setting the governor isn't enough. I had to set the MAX and MIN variables for frequency as well, because the scaling policies had them set to minimum, so what I do is

  1. Get the min and max scaling frequencies from CPU 0
  2. Divide them by a million to get the frequency in GHz
  3. Pipe the result through bc so I can get the result in floating point(BASH can only handle integers) - scale=1 is how many decimals
  4. Check if a scaling governor is supplied on the command line
  5. If not, set ONDEMAND - save some money when idling
  6. Run the cpufreq-set command in a loop on all CPU-s
    #!/bin/bash
    echo "Setting all CPUs to " "$@"
    CPUINFO_MIN_FREQ=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq)
    CPUINFO_MAX_FREQ=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
    MIN=$(echo "scale=1; $CPUINFO_MIN_FREQ / 1000000" | bc)"G"
    MAX=$(echo "scale=1; $CPUINFO_MAX_FREQ / 1000000" | bc)"G"
    
    echo "Minimum frequency: " $MIN ", Maximum frequency: " $MAX
    
    GOVERNOR=@0
    if [ $# -eq 0 ]
        then
            echo "No arguments supplied, using ONDEMAND governor"
            GOVERNOR="ondemand"
        else
            echo "Governor " $1 " supplied"
            GOVERNOR=$1
    fi
    
    for ((i=0;i<$(nproc);i++));
        do cpufreq-set -c $i -r -g $GOVERNOR  --min $MIN --max $MAX;
    done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .