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.)

htorque
  • 64,798
  • 2
    With "custom solution" you mean that a shell script is unacceptable, it needs to be a built-in GUI button? – j-g-faustus Jan 06 '11 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 06 '11 at 16:20
  • Check this page: http://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...) – j-g-faustus Jan 06 '11 at 22:47

8 Answers8

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.

htorque
  • 64,798
  • 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 '14 at 09:16
  • Please see alternative script in my comment to user49449's answer. – Sri Sep 11 '14 at 09: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
Elder Geek
  • 36,023
  • 25
  • 98
  • 183
user49449
  • 477
  • 10
    The -r related option doesn't do it for all the cores. We have to specify the cpu number with option -c 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 '14 at 09: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 '15 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 01 '16 at 12:51
  • 4
    Broken: Only sets governor for first core, according to cpufreq-info – kidmose Jan 14 '20 at 12:23
  • @kidmose finding is indeed correct. – Slbox Nov 02 '21 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
}
switch87
  • 220
  • You'll likely have more than 8 cores, so modify the "0..7" accordingly. – Raven Dec 10 '19 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 09 '20 at 15:57
8

You can do this for all cores at once by running

sudo cpupower frequency-set --governor performance
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

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.

Roiikka
  • 46
  • 4
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
side2k
  • 121
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 &quot;Minimum frequency: &quot; $MIN &quot;, Maximum frequency: &quot; $MAX

GOVERNOR=@0
if [ $# -eq 0 ]
    then
        echo &quot;No arguments supplied, using ONDEMAND governor&quot;
        GOVERNOR=&quot;ondemand&quot;
    else
        echo &quot;Governor &quot; $1 &quot; supplied&quot;
        GOVERNOR=$1
fi

for ((i=0;i&lt;$(nproc);i++));
    do cpufreq-set -c $i -r -g $GOVERNOR  --min $MIN --max $MAX;
done

jsaddwater
  • 121
  • 4