Android vs. Maemo power management: static vs. dynamic

Some of you might have heard about Google’s Android team proposal to introduce wakelocks (aka suspend-blockers) to the Linux kernel. While there was a real issue being solved in the kernel side, the benefits on the user-space side were dubious at best, and after a huge discussion, they finally didn’t get in.

During this discussions the dynamic and static power management were described and discussed at length, and there was a bit of talk about Maemo(MeeGo) vs Android approaches to power management, but there was so much more than that.

Some people have problems with the battery on Android devices, for some people it’s just fine, some people have problems with the Maemo, other don’t, so in general; your mileage might vary. But given the extremely different approaches, it’s easy to see in which cases you would have better luck with Maemo, and in which with Android–Although I do think it’s obvious which approach is superior, but I am biased.

An interesting achievement was shared by Thiago Maciera, who managed to get ‘5 days and a couple of minutes‘ out of the Nokia N9 while traveling, and actually using it–and let’s remember this is a 1450 mAh battery. Some Android users might have trouble believing this, but hopefully this blog post would explain what’s going on.

So lets go ahead and explore the two approaches.

Dynamic Power Management

Perhaps the simplest way to imagine dynamic power management, is the gears of a manual transmission car. You go up and down depending on how much power does the system actually needs.

In some hardware, such as OMAP chips, it’s possible to have quite a lot of fine control on the power states of quite a lot of devices, plus different operating power points on the different cores. For example, it might be possible to have some devices, such as the display on, and active, some other devices partially off, like speaker, and other completely off, like USB. And based on the status of the whole system, whole blocks can be powered off, other with low voltage levels, etc.

Linux has a framework to deal properly with this kind of hardware, the runtime power management, that originally came from the embedded world, and a lot from OMAP development, but is now available to everyone.

The idea is very simple; devices should sleep as much as possible. This means that if you have a sound device that needs chunks of 100ms, and the system is not doing anything else but playing sound, then most of the devices go to sleep, even the CPU, and the CPU is only waken up when it needs to write data for the audio device. Even better is to configure the sound device for chunks of 1 second, so the system can sleep even more.

Obviously, some co-operation between kernel and user-space is needed. Say, if you have an instant messenger program that needs to do work every minute, and a mail program that is configured to check mail every 10 minutes, you would want them to do work at the same time when they align at every 10 minutes. This is sometimes called IP heartbeat; the system wakes up for a beat, and then immediately goes back to sleep. And there are kernel facilities as well, such as range timers.

All this is possible thanks to very small latencies required for devices to go to sleep and wakeup, and have intermediary modes (e.g. on, inactive, retention, off), so, for example a device might be able to go to inactive mode in 1ms, retention in 2ms, and off in 5ms (totally invented numbers). Again, the more sleep, the better. Obviously, this is impossible on x86 chips, which have huge latencies–at least right now, and it’s something Intel is probably trying to improve effusively. All these latencies are known by the runtime pm framework in the kernel, and based on that it and the usage, it figures out what is the lowest power state possible without breaking things.

Note I’m not a power management expert, but you cant watch a colleague of mine explain the OMAP 3 power-managment on this video:

Advanced Power Management for OMAP3

And there’s plenty of more resources.

Update: That was the wrong link, here are the resources.

Static Power Management

Static power management has two modes: on and off. That’s it.

OK, that’s not exactly the case in general, but it is in the Android context; the system is either suspended, or active, and it’s easy to know in which mode you are; if the screen is on, it’s active, and if it’s off; it’ is suspended (ideally).

There’s really not much more than that. The complexity comes from the problem of when to suspend; you might have turned off the display, but there might be a system service that still needs to do work, so this service grabs a suspend blocker which, as the name suggests, prevents the system from suspending (until the lock is released). This introduces a problem; a rouge program might grab a ‘suspend blocker’ and never release it, which means your phone will never suspend, and thus the battery would drain rather quickly. So, some security mechanisms are introduced to grant permissions selectively to use suspend blockers.

And moreover, Android developers found race conditions in the suspend sequences in certain situations that were rather nasty (e.g. the system tries to suspend at the same time the user clicks a button, and the system never wakes up again), and these were acknowledged as real issues that would happen on all systems (including PC’s and servers, albeit rarely, because they don’t suspend so often), and got fixed (or at least they tried).

Versus

First of all, it’s important to know that if you have dynamic pm working perfectly, you reach exactly the same voltage usage than static pm, so in ideal cases they both behave exactly the same.

The problem is that it’s really hard for dynamic pm to reach that ideal case, in reality systems are able to sleep for certain periods of time, after which they are woken up, often times unnecessarily, and as I already explained; that’s not good. So the goal of a dynamic pm system is to increase those periods of time as much as possible, thus maximizing battery life. But there’s a point of diminished returns (read this or this for expert explanations), so, if the system manages to sleep 1s in average, there’s really not much more to gain if it sleeps 2s, or even 10s. These goals were quite difficult to achieve in the past (not these, I invented those numbers), but not so much any more thanks to several mechanisms that have been introduced and implemented through the years. So it’s fair to say that the sweet spot of dynamic pm has been achieved.

This means that today a system that has been fine-tuned for dynamic pm can reach reach a decent battery life compared to one that uses static pm in most circumstances. But for some use-cases, say, you leave your phone on your desk and you don’t use it at all, static pm would allow it to stay alive for weeks, or even months, while dynamic pm can’t possibly achieve that any time soon. Hopefully you would agree, that nobody cares about those use-cases were you are not actually using the device.

And of course, you only need one application behaving badly and waking up the system constantly, and the battery life is screwed. So in essence, dynamic pm is hard to achieve.

Android developers argued that was one of the main reasons to go for static pm; it’s easier to achieve, specially if you want to support a lot of third party applications (Android Market) without compromising battery life. While this makes sense, I wasn’t convinced by this argument; you still can have one application that is behaving badly (grabbing suspend blockers the whole time), and while permissions should help, the application might still request the permission, and the user grant it (who reads incomprehensible warnings before clicking ‘Yes’ anyway?).

So, both can get screwed by bad apps (although it’s likely that it’s harder in the static pm case, albeit not that much).

But actually, you can have both static and dynamic power management, and in fact, Android does. But that doesn’t mean Android automatically wins, as I explained, the system needs to be fine-tuned for dynamic pm, and that has never been a focus of Android (there’s no API’s or frameworks for that, etc.). So, for example, a Nokia N9 phone might be able to sleep 1s in average, while an Android phone 100ms (when not suspended). This means when you are actually using the device (the screen is on), chances are, a system fine-tuned for dynamic pm (Nokia N9) would consume less battery, than an Android device.

That is the main difference between the two. tl;dr: dynamic pm is better for active usage.

So, if Android developers want to improve the battery usage while on active usage (which I assume is what the users want), they need to fine-tune the system for dynamic pm, and thus sleep as much as possible, hopefully reaching the sweet spot. But wait a second… If Android is using dynamic pm anyway, and they tune the system to the point of diminishing returns; there is not need for static pm. Right? Well, that’s my thinking, but I didn’t manage to make Android developers realize that in the discussion.

Plus, there’s a bunch of other reasons while static pm is not palatable for non-Android systems (aka. typical Linux systems), but I won’t go into those details.

Nokia’s bet was on dynamic, Google’s bet was on static, and in the end we agreed to disagree, but I think it’s clear from the outcome in real-world situations who was right–N9 users experiencing more than one day of normal usage, and even more than two. Sadly, only Nokia N9 users would manage to experience dynamic pm in full glory (at the moment).

Upstream

But not all is lost, and this in my opinion is the most important aspect. Dynamic pm lives on the Linux kernel mainline through the runtime power management API. This is not a Nokia invention that will die with the Nokia N9; it’s a collaborative effort where Nokia, TI, and other companies worked together, and now not only benefits OMAP, but other embedded chips, and even non-embedded ones. Being upstream means it’s good, and it has been blessed by many parties, and has gone through many iterations, and finally it probably doesn’t look like the original OMAP SRF code at all. Sooner or later your phone (if you don’t have an N9) will benefit from this effort, and it might even be an Android phone, your netbook (if not already benefiting in some way), and even your PC.

Android’s suspend blockers are not upstream, and it’s quite unlikely that they will ever be, or that you would see them used in any system other than Android, and there’s good reasons for that. Matthew Garrett did an excellent job of summarizing what went wrong with the story of suspend blockers on his presentation ‘Android/Linux kernel: Lessons learned’, but unfortunately the Linux foundation seems to be doing a poor job of providing those videos (I cannot watch them any more, even though I registered, and they haven’t been helpful through email conversations).

Update: I managed to get the video from the Linux Foundation and pushed it to YouTube:

Here is part of the discussion on LKML, if you want to read it for some strange reason. WARNING; it’s huge.

About these ads

21 thoughts on “Android vs. Maemo power management: static vs. dynamic

  1. Android power management is highly dynamic. Devices are powered down when not in use, whether or not the screen is on. CPUs are parked in the lowest possible power states when idle (including full powerdown if the architecture allows for it).

    Android *further* shifts into full suspend which allows even lower power states (depending on architecture, kernel thread activity,e tc), whenever possible. Wakelocks allow us to know when it’s safe to go into that lowest power state, achieving additional power savings.

    In short, it’s easy to get confused by the names of things. It’d be interesting to look at power consumption graphs measured at the battery for comparable workloads on different architectures (that’s how we look at overall power use).

  2. +Brian Swetland

    Nice to see you here. Yes, as I said, Android does use dynamic pm, which is part of Linux upstream, and yes, devices power down selectively, thanks to all the kernel infrastructure.

    The key is, as you said; “when not in use”. So, the trick is to wake them up as less as possible, and Android API’s don’t seem to do anything to try to achieve that, like IP heartbeat, or ranged timers.

    Android *further* shifts into full suspend which allows even lower power states (depending on architecture, kernel thread activity,e tc)

    In the huge discussion in LKML it was agreed that there’s no difference between suspend and idle; they both drive the system to exactly the same voltage usage. This, of course, on the relevant architectures (e.g. OMAP and others, not x86).

    In short, it’s easy to get confused by the names of things.

    The names of things don’t matter, both suspend and idle mechanisms do exactly the same in the end. You participated in that discussion, so you should know that. I can dig down the exact comments from kernel experts where this was agreed by everyone if you want.

    It’d be interesting to look at power consumption graphs measured at the battery for comparable workloads on different architectures (that’s how we look at overall power use).

    You mean when the screen is off, and thus static pm enters into the picture. When the screen is on, the system is not suspended, and thus only dynamic pm is active, and thus the system that has been better fine-tuned for dynamic pm would perform better.

  3. Great article.

    Ignoring that I don’t think “opportunistic suspend” is the panacea to all the power management problems that plague this world, I just don’t see why the Android folks need the userspace wakelocks interface.

    All the pieces required to implement a fully-userspace ‘suspendd’ daemon that implements both wakelocks and aggressive suspend on its own — and potentially more tasks such as heartbeat service, etc. — are already there. Even webOS seemingly has a ‘powerd’ daemon that does the aggressive suspending, on the TouchPad at least: Snapdragon SoC, where dynamic PM doesn’t seem to be as effective as on TI OMAP.

    Considering that it can be fully done in userspace, that it does not have performance requirements and that it smells as a “policy” thing from a mile, I don’t understand why this wakelock interface is still being debated….

    The entire concept of suspending might make sense on x86, where the BIOS/APM/ACPI/whatever usually declares several predefined power states and provides proprietary bios calls/ACPI code/whatever to switch between them and implicitly configure all devices as appropriate.
    On ARM, there is no such firmware, so why artificially introduce this “static” suspended state again? Dynamic PM can and should be used to run all of the devices to the appropriate power saving configurations.

    And by the way, fanoush from TMO tested that a N810 with stock firmware could last up to the 30 days idling (no wi-fi, no bt, no radios). The N810 did not use aggressive suspending either, so that’s also quite an impressive number :)

  4. +javispedro

    I just don’t see why the Android folks need the userspace wakelocks interface.

    Very true, that point was also brought in the huge discussion.

    I don’t understand why this wakelock interface is still being debated….

    It’s not, AFAIK, I just took a long time to get around to write this post, and I was reminded by the nice results we are getting from the N9. Last I checked the issues that required changes in the kernel side are done single a long time, but in a different way, and they should be able to port all the wakelock stuff in their drivers to the new upstream API, and the user-space stuff can be managed entirely in user-space. But nobody from Android has had time to actually do that.

    And by the way, fanoush from TMO tested that a N810 with stock firmware could last up to the 30 days idling (no wi-fi, no bt, no radios). The N810 did not use aggressive suspending either, so that’s also quite an impressive number :)

    Indeed, somebody from Nokia mentioned something similar when he forgot his device on his desk for weeks and still had a lot of battery. But I don’t really think most people care about those use-cases :P

  5. I had always thought tickless kernels achieved the maximum possible power savings. (I’m a zero-knowledge person in this area.) Am I confusing aspects of power-savings?

    Also, who does the timer interrupt to the CPU, if the CPU is asleep? Is it a separate circuit?

  6. +Octavio Alvarez

    A tickless kernel achieves the maximum possible power savings if nothing is running. And assuming all the devices have properly implemented the dynamic pm routines of course. The trick is to get nothing running as much time as possible.

    Yes, there’s a separate circuit to wake up other devices. At least in OMAP 3 it’s called the wake-up domain.

  7. I would love to see a “hall of shame” for power-consuming applications and devices. I’d like to know what, in my laptop is the most power-consuming application, particularly if nothing else is running.

    Also, I wonder how much power-hungry the Linux kernel is itself. I wonder who wins if I leave Windows with the least amount of services enabled, with the least graphic options enabled vs. a CLI-only Linux distribution vs. a bare-minimum graphical Linux installation with nothing running (in the same laptop).

  8. Oh, forgot a comment: it does not matter how low the voltage of the CPU gets. You can use the same voltage for two different operations and use different electric *current*. That’s what matters.

  9. Hi I’m new to this blog, but I just wanted to point out that the vast majority of Android devices I’ve seen or used have had *terrible* standby battery lifetimes. On my own phone (LG Spectrum) standby results in -20mA, and in general Android devices are prone to drain huge amounts of battery loss overnight. My HP Touchpad running webOS loses a few % of its battery overnight, while with ICS running it loses 15-20%, even with no apps installed.

    Google doesn’t seem to care a whole lot about the battery life issue though.

  10. @sonicmerlin Google doesn’t seem to care about anything once they dominate, they forget about it.

    Google Mail, Google Reader, they barely add new features. Google Chrome the same.

    They most likely are only working on Google Plus, but if they manage to succeed, they’ll forget about it just the same.

  11. I don’t think so. While a lot of companies do this at some point or another, they don’t do it immediately and so blatantly as Google. Google clearly wants to dominate everything.

  12. I have a question that’s entirely off-topic, and may sound very stupid (I’m not a developer or anything). I’m under the impression that iOS, WP7, MeeGo, webOS, etc. are so snappy and responsive because they prioritize the UI thread (correct me if I’m wrong). They all manage to be so quick despite running on ARM equivalents of Pentium II (Cortex A8) and Pentium III (Cortex A9) CPUs.

    OTOH, I clearly remember how laggy and slow Windows could be on the old Pentium processors, and my old Mac OS 9 comp showed its age many times back in the day.

    I guess my question is why were desktop OS’s and even pre-iOS mobile OS’s (including Android) constructed differently? I’m not at all clear on how difficult it is to code, but wouldn’t UI priority have been common sense from the start for OS’s operating on low-powered systems?

  13. +sonicmerlin It’s more than prioritized; in iOS nothing else can run as long as the UI thread is running. I believe WP7 is similar, except that maybe it doesn’t even have multi-thread support.

    As for how much this is needed, I guess that depends on the capabilities of the UI; if the UI only refreshes at most at 20fps, then you most likely don’t need any of this, but if you render at 60fps, then you do (depending on the hardware).

    I believe iOS started to with 60fps, and to do that reliably they probably make it a real-time thread; nothing can run until that thread is done. This of course doesn’t make things faster, only gives the impression that it is faster.

  14. Seems like common sense to want your user-facing interface to be smooth as silk, even in a low FPS environment. The ability to temporarily shut down extraneous processes to prevent “hangups” in one’s interaction with the device adds such brilliant functionality.

    I’m reminded of the jump from single-core to the Core 2 Duo era and the resulting massive speedup. Simple things like alt-tabbing out of a game were made so much faster. I was mystified as to why dual-cores weren’t commercially available to consumers (outside of server environments) much earlier.

    Was the technology to prioritize UI in such a way available in the 90s and early 00’s? I can’t imagine Apple developed the coding methodology first.

  15. +sonicmerlin There are different strategies how to achieve that; what iOS does is really simple, but it probably wouldn’t work on Linux desktop. You have to remember that in Linux desktops you don’t have single thread doing all the UI; there’s quite a lot of components involved.

    Today there’s a lot of sophisticated ways to achieve that in the Linux desktop, but you need communication among many different components; X.org, GTK+/Qt, window manager, applications, kernel, etc. This was done in Maemo/MeeGo, but it would require much more effort to do the same in a typical desktop.

    Although there’s progress in this area, ideally you would not need this thread prioritization; if you use some advanced widget toolkit like QML, then the instructions that make the UI smooth go directly to the GPU and there’s no need for the CPU to be involved at all; specially not 60 times per second.

    As for the double-core speedup, that also depends on the kernel; I’m sure the speedup you gain in Linux is much more than what you gain on Windows, and the same applies to the scalability to 4, 8, or more cores. There have been a lot of people that have contributed to fine-tune different parts of the kernel to make it more scalable. This is where work on supercomputers benefit mobile, for example.

  16. Pingback: Surface Pro 3 - The problems thread - Page 60

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s