If you're a gamer, you probably find your computer's default CPU scaling (usually the "balanced" or "powersave" setting) is more than sufficient the majority of the time, but just occasionally, a game will run at its best when the CPU is set to maximum frequency all the time, instead of scaling up and down on demand. The recent F1 2017, ported and released for Linux very recently by our beloved porting heroes, Feral Interactive, is one such game that calls for this and it inspired me to hack together a quick and dirty script to make things a little bit more convenient. Because isn't that the best thing about scripts?
So, the typical way (from the commandline) that you change the CPU governor is like this:
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
And when you want to get out of high performance/maximum frequency mode and "save on the juice", you do as so:
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
But if you're like me and have a
fetish compulsion to pack up commonly used commands into a script, and maybe even later attach it to a hotkey, read on...
#!/bin/bash ## Script to toggle the CPU governor from powersave to performance and back again ## query=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) statement="Permission needed to change CPU governor. Please enter password..." if [ "$query" == "powersave" ]; then xterm -title "Activate \"Performance\" Governor" -class FXTerm -e "echo $statement && echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor && notify-send 'CPU Performance Enabled'" else xterm -title "Activate \"Powersave\" Governor" -class FXTerm -e "echo $statement && echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor && notify-send 'CPU Powersave Enabled'" fi exit 0
The script is very basic, but that's the kind of simplicity I love. So we create and store in a variable called query, the current CPU governor as reported in the
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor file. In the statement variable we also put a line of text we'll use more than once, so why not store it in a reusuable variable for the sake of clean code.
Then, we just run a simple if-else statement. We test if query equals "powersave", and if so, we activate the performance mode. Otherwise, we activate powersave. Simple, but it toggles properly.
It's worth noting that between the if-else statements you could simply just have the original basic code (i.e
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor etc) as long as you were already executing the script in an already opened terminal, but you'll notice what I've done is actually start an XTerm each time, with the -e switch, which then executes the relevant commands to change the scaling governor. The reason for this is to allow the script to be used as a kind of quick and dirty "dialog" window and also make things work as expected when called from a non-terminal instance, such as being bound to a hotkey. The biggest reason for this is obviously also that we need to execute sudo to supply proper permissions each time we want to change the CPU governor, so we need to make sure it brings up it's own window asking for our password every time instead of just failing silently in the background.
There's probably a way around having to use sudo each time, but eh, I did say this was quick. Plus, I'm so used to typing my password in it personally doesn't bother me. Also, pro tip: if you suddenly decide you don't WANT to change the CPU governor after executing the script, just hit CTRL+C. The XTerm window will disappear and nothing will happen.
You'll also notice I supplied a few extra arguments to XTerm, mostly just for the sake of making things look cooler and more interactive/informative. Let's have a quick look at those:
- -title: Simply gives our XTerm window a descriptive title.
- -class: OPTIONAL. I use this mostly to give the XTerm window a custom class which can then be targeted with i3wm, the window manager I use, to automatically set it as "floating" instead of tiled, thereby acting more like a dialog box and not screwing up my existing window flow.
- -e: As explained earlier, it simply runs the given command once the XTerm is launched.
You'll also notice, and this is also optional, I added in the
&& notify-send 'xxxx' command to the end of my CPU governor changing code. This is just a pretty and informative effect really, utilizing whatever your desktop environment or WM's notification daemon is (see the head image to this article for my example).
And that is basically it! Copy/paste the script and save it as whatever you want. I personally call it cpu-gov.sh and save it in my good old Scripts folder in my home directory.
Hotkeying it up
If you want to go a step further and actually hotkey this sucker (i.e bind it to a keyboard shortcut), well, this will depend entirely on what desktop environment or window manager you use. Most of the usual suspects, such as GNOME, KDE and Xfce, should make this pretty easy in their system settings once you navigate to the keyboard section.
From there, you can add custom keyboard shortcuts and then just type in the path to your saved script (eg.
/home/<user>/Scripts/cpu-gov.sh) once you chosen whatever key combination you desire. I personally use Super+Shift+G.
Bonus: i3wm users
I mentioned I use i3wm lately and that in the script I tell XTerm to use a custom class for a specific i3wm (or maybe many other tiling window managers as well) purpose.
Here's some relevant code for the i3wm config file (
# XTerm mimic dialog box (automated floating) for_window [class="FXTerm"] floating enable # toggle CPU governor (handy for some games like F1 2017 that run best with performance mode) bindsym $mod+Shift+g exec --no-startup-id /home/<user>/Scripts/cpu-gov.sh