My projects and thoughts

Shell Scripts and CPU Frequency Scaling

Posted on 2013-08-07

Many programmers have tried optimizing their programs only to realize that the optimizations actually makes them slower. Finding the cause of poor performance requires keeping an open mind. I never expected my program to run slower because the OS lowered the CPU frequency.

This behavior can easily be observed when running shell scripts. Shell scripts don't do much more than spawn new programs and wait for them to complete. Every new process is put on an idle CPU. This sounds great at first, but idle means low CPU frequency.

$ time ./test.sh
real	1m46.299s
user	0m7.204s
sys	0m14.852s

$ for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do sudo sh -c "echo performance > $i";done
$ time ./test.sh
real	0m48.928s
user	0m3.252s
sys	0m7.208s

$ cat test.sh
#!/bin/bash
c=1
while [ $c -le 100000 ]; do
    md5sum test.sh > /dev/null
    ((c++))
done

Popular Gnu/Linux distributions come with CPU frequency scaling enabled. If you frequently run configure scripts or non-parallelized build scripts, you can gain a lot of performance by disabling it.

I originally posted this as a question on Stack Overflow, but reposting here for its educational content. The best workaround I've found to my own question so far is the C equivalent of this:

#!/bin/sh
grep ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor >& /dev/null &&
    echo 'CPU frequency scaling governor "ondemand" detected. This will be slow...'
...