Sunday, March 20, 2011

Energy management in Linux: kernel version

UPDATE here.

Continuing from this post I want to show how the choice of a kernel version can have an important impact on the energy consumed by a computer (in my case, a Lenovo x200s).

I've been working on the battery quite often lately and I have noticed that the power consumption can vary quite a bit from kernel to kernel. This was of course a very subjective appreciation as the load could vary, the number of firefox tabs, the task I was doing or even how fast did I type.

The other day, however, after updating to kernel 2.6.38 i realized that idling, the computer barely went under 7W. I remember perfectly that "before", it could idle at aroung 6.0W, even with the wifi on, and now it was off. I decided to try an older version, and decided for 2.6.34. This is because from 2.6.35 to 2.6.37 there has been a very nasty bug that prevented my Intel Wifi 5300 agn card from injecting packets do to the famous -1 bug. Yes, I do audit my own wifi very often, why you ask? ;)

So I hacked the PKGBUILD file a bit and installed a custom kernel along with my custom 2.6.38 one. I booted the laptop, turned the wifi off, closed Dropbox (powertop doesn't like it) and let it sit idle for a while. After a few minutes I closed the lid, previously deactivating sleep-on-close, to see how turning the screen completely off affects thigs. You can see the results on the following graph:

Energy consumption on a Lenovo x200s, KDE 4.6.1, WiFi & Bluetooth off, SSD disk, Screen 6/15 -> off

The result was so different that I used the .config from the 2.6.34 kernel to recompile the .38 and see maybe I missed something. As you can see from the blue line, that is not the case, the .38 kernel just consumes consistently 1W (~20%) more than the .34 version...

Take this results as they are: two different kernel versions with a particular custom configuration on a particular hardware.

I am NOT saying that kernel 2.6.34 is more energy-efficient than 2.6.38 as a general rule.
I AM saying that some kernel versions are more efficient than others on some hardware - test your versions on your hardware and pick the one that works best for you.


mikar said...

Hey there Bart,

i noticed the same thing. I've been very happy with the consumption of my x200s for a while now. With WiFi on and ~5/15 brightness it consumed 5.1 watts unless the fan was spinning which would add another ~0.5 watts to that (@~2000rpm). When turning everything off and lowering the display brightness to the minimum i could even drop the power consumption to 4.7W.
When actively surfing it was 6 to 8 watts consumption.
I hadn't updated the system for a while. I'm pretty sure i was running 2.6.34 at that time too.

A couple of days (or was it a week?) ago i upgraded to .37-ARCH and ever since then I'm idling at no less than 6W and overall the consumption is in fact roughly 1 watt higher now.

Just thought I'd back up your theory.
Not that I'm complaining, I'm still extremely happy with my X200s :).


Bart said...

Wow, actually I haven't seen such low values my self! Usually when actively using the computer, it goes around 9 or 10 watts.

What desktop environment/browser do you use? How many interruptions per second does powertop (as root) show?

For me with idle KDE 4.6.2, fan on and wifi off it consumes 5.9W, with ~50 int/s. As soon as I start Kdevelop it jumps to 7W :( And with firefox is similar, maybe even a bit worse...

mikar said...

It's the hardware, really. I use an Intel SSD and a LED-Display. A X200s with CCFL-Display and HDD would consume around 2 Watts more on average.

It's crazy in Windows Vista/7 and the only reason why i still have a dual-boot. With proprietary drivers I get 3.98 W idle and 2.9 W if i turn off the display:
Just for fun I'd love to try one of those new high capacity 9c accus for the X200/X201. With the display turned off you could get 30+ hours :s

Anyway, i'm afraid i was too quick to support your observation regarding kernel regression. Turns out i had Laptop-Mode-Tools disabled which accounts for the additional Watt in power consumption. For once, it's not the kernel. Just me confusing myself yet again \o/.

But i can definately confirm that some kernels are more efficient when it comes to power consumption on the X200s.
I think it was somewhere around kernel version 2.6.32 when the power usage of my X200s dropped from ~7W idle to 5W idle. This is quite possibly related to the WiFi power saving feature being reintroduced into the kernel around that time.
Ever since then power consumption is quite consistent.

Since you asked and a check was overdue anyway, here's what powertop tells me when:
idling, wifi/bt/fan off, brightness at 1/15 ->
idling, wifi/fan on, bt off, brightness at 5/15 ->
surfing very lightly, e.g. typing this right now --> 5.7 - 6.4 Watts.

Admittedly, I'm using a very minimal UI. Just Openbox, Firefox and conky (as system monitor) essentially.
If i kill conky, xcompmgr, minilogd and the kernel watchdog I can get it down to less than 1 wakeup per second when idling.

But to be perfectly honest it's all the same. Add a few hundred wakeups/sec and an even less efficient browser than firefox and you're probably still only looking at a difference of a few hundred miliwatts.

I've tried almost everything, e.g. manually stripping down and enabling any and all power saving features in the kernel, using different DEs, manually tweaking all the power saving settings i could find etc.
But overall there are only three ways i really affected the power consumption:
1) SSD: As mentioned above, it shaved off 1.5 Watts on average. Doesn't sound like much but it's actually 20% more battery life.
2) LMT (laptop-mode-tools): It works much better than altering the power saving settings manually. Don't ask me why. Saves me pretty much exactly 1 Watt.
3) Display: I'm often in the library, connected to a wireless network, reading a book and every now and then taking notes on the laptop.
So whenever I'm not typing something i simply turn off the display.
You can bind xset dpms force off to a hotkey (i did it via acpid to FN+F3).
The upside when compared to suspending the laptop is you can resume work instantly and you don't have to reconnect the wifi. Suspending too often also puts strain on the system particularly the HDD/SSD.
Doing that saves another Watt, even at lowest brightness.

Those three things are what got me 30-50% more battery life. Everything else i could do was just peanuts in comparison.

One more thing though:
You can try disabling I/O access to the docking station in the BIOS. With some BIOS-Versions this will save you 0.5 Watts power consumption. It's some sort of acpi bug i guess.
Another thing i noticed about the X200s: Often after suspending, power consumption will be ~2 Watts higher than normal. This can only reliably be fixed by a reboot. Did you notice the same behaviour?

Sorry for the wall of text. :o

Bart said...

Just finished testing, here are the results.

My hardware:
X200s, SSD Intel X25M-G2, WXGA+ LED, Intel5300agn, 4GB DDR3
My software: Linux x64, KDE 4.6.2, firefox 4, conky, wicd, kdevelop, dropbox, apache, mysql, yakuake

Starting point: just unplug the laptop, 600 int/s, power consumption: 12-15W (!)
killall knotify4: 600 int/s, 10-13W
close firefox: 270 int/s, 7-9W
close kdevelop: 200 int/s, 7-8W
killall knotify4 (again): 50-100 int/s, 5.8-6.5W
kill wifi: 50-100int/s, 5.8-6.5W (no gain)
brigthness 0/15 (still on): 50-100int/s, 5.2-6.0W
screen off: 50-100int/s, 4.2-5.0W
single-user mode: 10int/s, 4.0W
fan off: 10int/s, 3.8W
back here to post: 12.5W

Last two results with screen off.

So, summing up:
Lowest acheivable: 3.8W.
Lowest acheivable with screen on: 5.0W.
Lowest acheivable with working SW: 7.0W.
Usually when working in the UBahn: ~9W

Seems that the hardware isn't _very_ different (0,3W idle), a lot depends on the sofware. I need "5W+ of software" to get my job done. If I get some time I will repeat the test with the .38 kernel, to see if anything changes.
Are you using a 64 bit kernel? How much RAM do you have?

About suspending: I very rarely turn my computer off, and suspend/resume it several times a day, so it's really hard to tell :/ All these results were taken after several suspend/resume cycles today. Usually I only reboot for a kernel update or when the wifi dies (dmesg "MAC is in deep sleep". Has it happened to you?).

BTW, I also have xset via acpi handler, but on FnF2 ;)

mikar said...

WiFi troubles me too.
It hasn't died on me yet though. It's just painfully slow. When i should be getting up to ~9 MB/s i usually only get ~0.3 MB/s x-fer speed in my LAN over wireless.

Interestingly enough, wireless often dies on me when using Windows (Vista). Can by fixed by a reboot though.

Any experience with slow wifi on your part?
And are you currently living in Germany? Or where else would you use "UBahn" as transportation? :P

Bart said...

I had some problems with the WiFi speed but never so bad, always comparable to 11g speeds (1 - 1,5MB/s) and lately it works better. But when it dies I also have to reboot the computer to get it back to work, no other thing does the trick, which is annoying. Since I almost never use Windows I can't say who is to blame for this, but it looks that it might be the card itself :/

And yes, I'm doing a PhD in Munich now :)

PS: do you use 64 bit system? How much RAM do you have installed?

mikar said...

I have 4GB installed but I'm using 32bit Arch. I rarely use more than 400 MB of RAM anyway so I'm in no hurry to switch to 64bit.

Regarding your wifi issue, i got curious, googled around and found something:
Try disabling vPRO/AMT in your BIOS. Apparently it can conflict with WiFi on some hardware level. See here:
I also have to correct myself. While wifi in Windows sometimes just dies I don't have to do a reboot to make it work again. I meant to write "reconnect" in my previous post.

At any rate, have fun with your PhD. Munich is pretty cool, too, though it's been a while since I've last been there.

mikar said...

Hey, me again. Tonight, I've installed Kernel from testing repository to fix my slow WiFi transfer rates. Thankfully, it did.
However, I can now confirm that 2.6.38 did increase power consumption somewhat. For me it's 0.3 - ~0.7 W.

In 2.6.37:
WiFi/BT/fan off, brightness 1/15 -> 4.8 W
Now with 2.6.38 it's 5.4 W.

In 2.6.37:
WiFi/fan on, BT off, brightness 5/15, idling on this page -> 5.3 W
Now with 2.6.38 it's 5.6 W.

In 2.6.37:
same as above but lightly surfing, i.e. typing this now and switching a few tabs -> 5.7 - 6.4 W
Now with 2.6.38 it's 6.1 - 6.7 W.


mikar said...

Just one more thing:

What did you use to measure power consumption and make the graph?

Bart said...

Sorry for the delay, I was quite busy lately.
To measure power consumption, a bash script ~"while true cat BATTERY_FILE >> log sleep TIME done".
To plot the files, gnuplot.

Bart said...

About the vPRO crap I already read about it, but didn't help much/at all.
BTW, if you update the BIOS, update also the vPRO firmware even if you're not using it, else it takes 20-30min(!) to pass the BIOS when booting.

mikar said...

Incidentally, just yesterday I did a BIOS update with the Lenovo BIOS-Update utility (in Windows). It seemed like the first update process didn't rewrite all the 32 blocks so I ran it a second time.
Mid-update I was rewarded with a blue screen and all i could do was reboot.
I think i actually went a little bit into shock thinking i just broke my BIOS :O
Miraculously, my laptop is still booting.

Anyway, i hope you don't mind my going-offtopic but i've just been trying to reproduce your gnuplot 2d chart. I did manage it but I think I'm doing it wrong.

Where do you get the column for the x-axis (time in secs) from?

What I'm doing:

while true; do cat /sys/devices/platform/smapi/BAT0/power_now >> power2.dat && sleep 1; done

Then i get a file with content like this:

So what i then have to do before using that file for plotting is manually add a second column and remove all the minuses so it looks like this:
5892 1
5892 2
5911 3
5911 4
6823 5

Could you maybe share your way with me? :o)
I'd be glad if you could be explicit as i'm completely new to gnuplot.

Thanks in advance,

Bart said...

It's easier than that. If you don't have two columns gnuplot just sequentially numbers the values in the only column you have. And you can let gnuplot take care of the minuses. Try something like:

gnuplot -p -e 'plot "datafile.dat" using (-$1) with lines title "TITLE HERE"'


mikar said...

Thanks, I've toyed a little with gnuplot, here are my results ;)

Comparison 2.6.37 - 2.6.38 (idle):

Kernel 2.6.38 consumes about 0.5W more power than 2.6.37 when idling.

Also, here's one with light surfing, brightness 4/15, fan ~2000 rpm on 2.6.38:


Bart said...

Kernel bug seems to be confirmed: (via