Linux, low power / low heat for summer

Sometimes I play browser games including  This loads the CPU and GPU, and in this summer weather my laptop gets too hot and heats up the room.

I tried using Chrome with the GPU disabled, but the browser games would still cause the GPU to ramp up to full clock rate. I guess the X server was using the GPU.

google-chrome --disable-gpu   # does not always prevent GPU clocking up

So here’s what I did:

For the NVIDIA GPU, we can force the lowest power mode by adding the following to the “Device” section in /etc/X11/xorg.conf:

# Option "RegistryDwords" "PowerMizerEnable=0x0;"
Option "RegistryDwords" "PowerMizerEnable=0x1; PerfLevelSrc=0x3333; PowerMizerLevel=0x3; PowerMizerDefault=0x3; PowerMizerDefaultAC=0x3"

Unfortunately the “nvidia-settings” tool does not allow this.  It is necessary to restart the X server in order to change this setting.  Just swap which line is commented out.

Given that we are keeping the GPU cool like this, Chrome works better with the GPU enabled not disabled.

For the CPU, setting “scaling_governor=powersave” does not force the lowest power mode, and the CPU still clocks up and gets hot.  But we can set “scaling_max_freq” to stop Linux from raising the clock speed.  I’m using this shell script “cpu_speed“:

cd /sys/devices/system/cpu
for cpu in cpu[0-9]*; do
 cd $cpu/cpufreq
 case "$cmd" in
 info) echo $cpu `<scaling_cur_freq` `<scaling_min_freq` `<scaling_max_freq`
 slow) cat cpuinfo_min_freq >scaling_min_freq
 cat cpuinfo_min_freq >scaling_max_freq
 fast) cat cpuinfo_min_freq >scaling_min_freq
 cat cpuinfo_max_freq >scaling_max_freq

I can run it with “cpu_speed” to see the current speed, “cpu_speed slow” to fix the clock at the lowest speed, and “cpu_speed fast” to allow the clock to go up to the maximum speed.

This “temperature” script shows the NVIDIA GPUCurrentPerfLevel, GPUCoreTemp, and CPU temperature info:

set -a
: ${DISPLAY:=:0.0}
nvidia-settings -q GPUCurrentPerfLevel -q GPUCoreTemp
acpi -t
) 2>/dev/null |
perl -ne 'print "$1 " if /[:,] (\d+)\./'

Finally, I can reduce the screen resolution to decrease the load on the GPU and CPU.  “xrandr” with the NVIDIA driver does not allow me to change the resolution directly, but there is an option to scale the display.  This gives much smoother performance in the browser games, and the lower resolution doesn’t hurt.


xrandr --output DP-2 --scale 0.5x0.5


xrandr --output DP-2 --scale 1x1

Anyway, now I have my laptop set up to run cool by default.  This doesn’t hurt for most things I am doing with it, and I feel it’s less likely to explode and burn down our house.

Posted in Uncategorized | Leave a comment

Chrome memory abuse, and “swap space” rant

I like the Chrome browser, but the memory usage is fscking ridiculous.

I have a slightly older computer at work, if I open 4 or more tabs in Chrome the computer will grind to a halt, and I gotta wait perhaps a few minutes for it to swap everything out then I can close the tabs. 150MB for a tab, that’s just way way way too much.

Personally I strongly dislike “virtual memory” in the sense of swapping to disk. I’d much rather get a (non-fatal) “out of memory” error than have the computer grind to a halt, which is what happens when a virtual memory computer goes a bit over its RAM. I don’t want to click a different window that I haven’t used for a while and have to wait for 3 minutes while the computer loads it from disk again and tries to figure out what to swap out. If we didn’t use swap, programmers (looking at you, Google) would be more careful not to waste memory.

Computers are not all that much more functional than they were in to 1990s, or even the 1980s, for regular office tasks such as wordprocessing and spreadsheets – and those computers although technically slower were actually more responsive in many cases because they did NOT grind to a halt due to swapping.


Posted in Uncategorized | 1 Comment

How to Divide by Zero: a/0 = b ⟺ a = 0

TLDR: Division by zero is not as scary as it’s made out to be:

a/0 = b ⟺ a = 0

Division is multiplication, backwards. These two equations are exactly equivalent, by definition:

a/c = b

a = b×c

It’s easy to understand division by zero if we look at the equivalent multiplication.

a/0 = b

a = b×0

For any real number b:

a = b×0 = 0

a = 0

There are two cases with division by zero:

If a = 0, then a/0 = b is unconstrained, any real number b satisfies the equation. You can discard such an equation which does not constraint the result.

If a ≠ 0 then a/0 = b is contradictory. There is no real number b which satisfies that equation. This is still useful to know; “there is no answer” can be a sort of meta-answer. For example if trying to solve a system of equations of static forces, “there is no answer” might mean you need to consider a different design for your bridge!

There is no need to consider advanced concepts such as limits in order to fully understand division.

In short, a/0 = b is true if and only if a = 0.

If you see such an equation a/0 = b, you may simplify it to a = 0.

a/0 = b ⟺ a = b×0 ⟺ a = 0

a/0 = b ⟺ a = 0

I posted this here about a year ago:

Posted in Uncategorized | Leave a comment

error handling in C

I started writing a set of error handler macros for C, based on “Zed’s Awesome Debug Macros”

The implementation is quite ugly, and depends on a couple of GNU extensions.  This is not ideal, and I would like to improve it if possible.

The idea is to call functions via “wrapper macros”, which take care of checking for errors.  Here’s an example:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "kiss.h"

int main(void)
	char *space = NULL;
	FILE *fp = NULL;
	space = MALLOC(1000);
	space = REALLOC(space, 10000);
	fp = FOPEN("asdfasdf", "r");

Output when I run it:

[INFO]  test1.c:11 main: Hello
[ERROR] test1.c:14 main: fopen failed: asdfasdf: No such file or directory

Output when I build it with -DNDEBUG and run it:

fopen failed: asdfasdf: No such file or directory

In most cases, I can add a wrapper macro with one short line of code:

#define MALLOC(...) CHK(malloc, __VA_ARGS__)
#define REALLOC(...) CHK(realloc, __VA_ARGS__)
#define FREE(ptr) (free(ptr), ptr = NULL)

#define FOPEN(path, mode) ({ char *p = path; FILE *rv = fopen(p, mode); CHECK(rv, "fopen failed: %s", p); rv; })
#define FCLOSE(fp) (ZERO(fclose, fp), fp = NULL)

The FOPEN macro is longer. I added the file name to the error message.

FREE is not checking for errors. It sets the pointer to NULL after the free. FCLOSE checks for errors and sets the FILE * to NULL.

I also wrote wrappers for some SDL and SDL_image functions, just a few so far.

Here is a short SDL example using the macros:

and the equivalent code without the macros, which is much longer:

I’m in two minds about this. On the one hand, I think these wrappers can make C code shorter, safer, more readable, and more maintainable. On the other hand, it might be best to avoid macros, the implementation is ugly, and it uses two GNU extensions: ##__VA_ARGS__, and ({ statement expressions }).

Please let me know what you think. (Without being too scathing, please… I respond better to kindness!)

Posted in Uncategorized | 3 Comments


I wrote a simple program ramp-io, based on the redshift code, to read and write the xrandr gamma ramps for Linux / X11.  This enables me to define my own gamma ramps, and switch ramps quickly from the command line.  My preferred ramp is red-inv, dim inverse video with a low colour temperature (more red, less blue), and I set the LCD hardware brightness to maximum to reduce LED PWM flicker.  I find this is relatively easy on the eyes for work, compared to the normal glaring white backgrounds.

Posted in Uncategorized | Leave a comment

printf “%q ” in bash, to escape arguments

I learned a useful trick with the bash shell today.

We can use printf “%q ” to escape arguments to pass to the shell.

This can be useful in combination with ssh, in case you want to pass arguments containing shell special characters or spaces. It can also be used with su -c, and sh -c.

The following will run a command exactly on a remote server:

sshc() {
        remote=$1 ; shift
        ssh "$remote" "`printf "%q " "$@"`"


sshc user@server touch "a test file" "another file"
Posted in Uncategorized | Leave a comment

job control in the shell

Job control is a basic feature of popular UNIX and Linux shells, such as “bash”.
It can be very useful, so I thought I’d make a little tutorial on it…

^C    press Ctrl-C to interrupt a running job (you know this one!)
^\    press Ctrl-\ (backslash) to QUIT a running job (stronger)
^Z    press Ctrl-Z to STOP a running job, it can be resumed later
jobs  type jobs for a list of stopped jobs (and background jobs)
fg    type fg to continue a job in the foreground
bg    type bg to continue a job in the background
kill  kill a job, e.g. kill %1, or kill -KILL %2
wait  wait for all background jobs to finish

You can also use fg and bg with a job number, if you have several jobs in the list.

You can start a job in the background: put an &-symbol at the end of the command. This works well for jobs that write to a file, but not for interactive jobs. Things might get messy if you have a background job that writes to the terminal.

If you forget the % with kill, it will try to kill by process-id instead of job number.  You don’t want to accidentally kill PID 1!

An example:

vi /etc/apache2/vhosts.d/ids.conf
find / >find.out &
fg 2
bg 2
kill %2
Posted in Uncategorized | Leave a comment