Forcibly underclocking at night

Solution 1:

Here's a program that does what you want:

#!/usr/bin/env python
# coding: utf8

import time
import sys
import commands


USER = commands.getoutput("cat /var/log/auth.log | grep " +
    sys.argv[0]).split("sudo:")[1].split()[0].strip()


def is_idle():
    return int(commands.getoutput("xprintidle")) >= 10 * 60 * 1000

def is_night():
    return time.localtime().tm_hour in (22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

def is_stumm():
    return "RUNNING" not in commands.getoutput(("sudo -u %s pacmd " +
        "list-sinks | grep RUNNING") % USER)


def main():
    powersave = False
    while 1:
        if is_idle() and is_night() and is_stumm():
            if not powersave:
                print "going into powersave mode"
                commands.getoutput("echo powersave > " +
                    "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor")
                powersave = True
        else:
            if powersave:
                print "going into ondemand mode"
                commands.getoutput("echo ondemand > " +
                    "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor")
                powersave = False
        time.sleep(0.5)

if __name__ == '__main__':
    assert commands.getstatusoutput("xprintidle")[0] == 0, (
        "you need to `sudo apt-get install xprintidle`")
    assert commands.getoutput("whoami") == "root", (
        "you need to be root to run this program")
    main()

Note your preferences:

  • ... >= 10 * 60 * 1000
  • ... tm_hour in (22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) and
  • "RUNNING" not in ...

I'm using pulseaudio to find out if a movie is playing. This also affect music.

Solution 2:

You can force your cpu scaling using:

cpufreq-selector -f [frequency]

There are a few more options (i.e. specific cpu, or selecting a governance rather than a speed) This does assume that your motherboard/cpu allows Ubuntu to manually control the scaling (apparently this is not always the case.)

The rest can be applied using a script, however you're being quite demanding of it ^_^. If you need an instant response that I think you have to have something periodically polling your system. From my, some what limited, knowledge there is nothing that announces the conditions you've specified.

A place to start investigating, however, is a screensaver. This turns on after a set period of inactivity (which would also be true at 10pm-9am) and can be inhibited by movie players. If you made a screensaver that scaled down the CPU when initializing, and restored it on wake, then you'd have what you want.

Unfortunately that's as far as I can take you, knowing nothing about screensavers and how they work.

Good luck.

Solution 3:

You may not actually save more power by using the powersave governor.

Depending on your workload, finishing a work item quickly by expending a little more power and then returning to a deep sleep state rather than working for extended times with reduced power consumption may give better results.

Depending on your application, it may also be worthwhile to install a dedicated server with lower power requirements and a properly dimensioned power supply for that load, and simply turn off the desktop at night.

Solution 4:

powernap is a handy tool for things like this, the nice thing is it looks at your process table to see if your system is busy, not your idle time at the keyboard.

Have you measured the powersaving for each governor? Like Simon I am skeptic that that would add up to a significant amount vs. getting the work done faster or trying to tune something like the monster video card.

powernap can be configured to just execute the governor switch or perhaps if your hardware supports it use the Wake On Lan (WOL) feature to take real naps in the middle of the night until it's needed.

  • Blog post from the author.