Laptop Power Conservation with Windows Bridge

In these days of ever-increasing mobile computing, laptop power consumption is ever more important. With laptops making up more than 50% of the computer sold last year, it is critical that users have all-day computing power when they're on the move. But paying attention to laptop power consumption is not important just for the user; increased use of battery-powered laptops results in lower IT power consumption costs. Computer usage is responsible for 7% to 18% of the electricity bill for a medium-sized company. While hardware providers are increasing battery life, It is critical that software developers don't inadvertently undercut those gains through their application's power draining practices.

A very good PDC session by Pat Stemen, Extending Battery Life with Energy Efficient Applications, includes a detailed explanation of the technological improvements in Windows 7 and the tools that come with it. Power management in Windows 7 will be a topic for future blog posts. In this blog post we will look at Vista’s power management APIs and focus on the managed power wrapper in the new release of the Windows Vista Bridge Library.

There are a few steps that developers can take to reduce their applications’ power consumption. First, try to keep the application’s CPU usage as close to idle as possible at all times. (CPU idle state = CPU usage of less than 2%) When the CPU is in idle or close to idle state, the CPU enters a low-power state that reduces its clock frequency, resulting in significant battery power conservation. As developers, we can help maintain a low clock ratio by using events and asynchronous notifications rather than a timer to poll (query) a value. When an application polls at a high rate (high frequency), it increases CPU usage and power consumption.

The following chart illustrates how increasing timer resolutionCPU_Power_Timer_Resolution increases the power consumption. Changing the Windows default timer resolution from 15.6 milliseconds to 1 millisecond can result in an up to 20% impact on battery life, because the frequent timer interrupts will prevent the processor from entering low-power states. With the default timer resolution, the CPU power consumption can be low as 0.1 watts which is a fraction of the overall computer’s 11 watts power consumption. But when increasing the timer resolution to 1 millisecond, the CPU power consumption raises to 1.5 watts affecting the overall computer power consumption by 2 watts.

Second, if an application launches a service that must wait for some event to happen, such as when a USB thumb drive is inserted, don’t launch the service until after the event occurs. It will be easy to implement this recommendation with the new Windows 7 Service Control Manager, which Vikram Singh presented during PDC in a session called Designing Efficient Background Processes.

Last, but by no means least, applications should be power aware. The power state of the computer can either be AC power, battery power, or UPS. To be power aware means that an application takes into account the current power state of the computer and acts upon that state in a way that minimizes power consumption. For example, an application should not start any non-critical operations while running on battery if it can postpone those operations to a later time without degrading the overall user experience.

Clearly, power awareness is a critical step in optimizing application power demands. How do we ensure that our applications are power aware?

To do this, we will use the Windows Vista Bridge Library. This library includes a whole section dedicated to bridging between the native power API and .NET. But there is one class within the library that is especially important for power aware managed code application. The PowerManager enables applications to register for power events and query the current power state. The PowerManager is a static class that the application can use at any given time simply by accessing its properties. The PowerManager keeps its power state accurate at all times by running a thread in the background that listens to OS power events. This thread has minimum to no affect on the application power consumption.

Here are some of the properties / functions that the PowerManager exposes regarding the power state:

Property or Function

Description

PowerManager.PowerPersonality

Specifies the the current power scheme

PowerManager.PowerSource

Specifies the power source currently supplying power to the system

PowerManager.IsBatteryPresent;

True if battery is present (just if a laptop has one)

PowerManager.IsUpsPresent;

Specifies whether power UPS is present

PowerManager.IsMonitorOn;

Specifies whether the monitor is on

PowerManager.MonitorRequired;

Specifies whether the monitor is set to remain active

PowerManager.IsBatteryShortTerm;

Specifies whether the battery is a short term battery

PowerManager.BatteryLifePercent;

Specifies the remaining battery life

PowerManager.GetCurrentBatteryState()

Gets a snapshot of the current battery state, nand updates the PowerManager

The PowerManager also exposes set of events that an application can register in order to receive notifications when there is a change in the power status:

Event

Description

PowerManager. IsMonitorOnChanged;

Raised when the monitor status changes

PowerManager.BatteryLifePercentChanged

Raised when the remaining battery life percentage changes

PowerManager.PowerPersonalityChanged

Raised each time the active power scheme changes

PowerManager. PowerSourceChanged

Raised when the power source changes

PowerManager.SystemBusyChanged

Raised when the system will not be moving into an idle state in the near future; applications should be designed to take advantage of this time to run their tasks, rather than running them during otherwise idle CPU periods

Note that Windows Vista and Windows 7 will always try to reach idle state; however, sometimes the system acknowledges that an idle state will not be reached anytime soon due to an IO or other operation. The OS can notify any interested applications that the system is “busy” and will not switch to an idle state anytime soon. This would allow the application to start running some tasks using the high utilization CPU as is.

The Vista Bridge Library has an example showing how to use the PowerManager . It is a simple WPF application that uses the PowerManager to display the current power status and update the status upon power status change. When running the application you’ll see a simple window listing the PowerManager properties and the current power status. When switching from AC power to battery while running on a laptop you will notice the change to the Windows theme but also that the application has captured the power changes.

 

VB_Power

 

 

Here is the code snippet for capturing current power status:

    1:  private void GetPowerSettings()
    2:  {
    3:      settings.PowerPersonality = 
    4:          PowerManager.PowerPersonality.ToString();
    5:      settings.PowerSource = 
    6:          PowerManager.PowerSource.ToString();
    7:      settings.BatteryPresent = 
    8:          PowerManager.IsBatteryPresent;
    9:      settings.UpsPresent = 
   10:          PowerManager.IsUpsPresent;
   11:      settings.MonitorOn = 
   12:          PowerManager.IsMonitorOn;
   13:      settings.MonitorRequired = 
   14:          PowerManager.MonitorRequired;
   15:      
   16:      if (PowerManager.IsBatteryPresent)
   17:      {
   18:          settings.BatteryShortTerm = 
   19:          PowerManager.IsBatteryShortTerm;
   20:          settings.BatteryLifePercent = 
   21:          PowerManager.BatteryLifePercent;
   22:          settings.BatteryState = 
   23:          PowerManager.GetCurrentBatteryState().ToString();
   24:      }
   25:  }

 

Here is the code snippet for registering to the events:

    1:  // Adds event handlers for PowerManager events.
    2:  private void CapturePowerManagementEvents()
    3:  {
    4:      PowerManager.IsMonitorOnChanged += 
    5:          new EventHandler(MonitorOnChanged);
    6:      PowerManager.PowerPersonalityChanged += 
    7:          new EventHandler(PowerPersonalityChanged);
    8:      PowerManager.PowerSourceChanged += 
    9:          new EventHandler(PowerSourceChanged);
   10:      if (PowerManager.IsBatteryPresent)
   11:              PowerManager.BatteryLifePercentChanged += 
   12:                  new EventHandler(BatteryLifePercentChanged);
   13:   
   14:      PowerManager.SystemBusyChanged += 
   15:          new EventHandler(SystemBusyChanged);
   16:  }

 

Now it is up to you. Go ahead and download the Windows Vista Bridge Sample Library, and start using Vista Power APIs - they all work just as well on a Windows 7 machine.

(This blog and the application sample were written and tested on a Windows 7 machine)

J