'Green' Code DevelopmentThis article is sponsored by Intel AppUpSM developer programUltrabook(TM) is the latest word in the mobile device world. Ultrabook devices are slim, lightweight, as powerful as a PC, and as portable as a tablet. Consumers want Ultrabook devices for these features, but as a software developer, what I find more interesting is understanding how to make my applications more Ultrabook friendly. With Ultrabook devices, as with any mobile device, power-efficiency is very important. Users want to use their devices as long as possible without charging the battery. Let's take a quick look at the main parts that affect power efficiency with any mobile platform--the battery, the hardware, and the software. BatteryThe battery is the main power source for mobile platforms. Manufacturers of batteries and storage cells try every year to increase battery capacity. HardwareThe hardware consumes power to perform most tasks and is the only power consumer in the system. Hardware vendors strive to continuously improve device hardware in an effort to try to increase battery life. For example, every new Intel CPU is more power efficient than previous versions. SoftwareSoftware is the main reason why we use mobile platforms. Software does not consume power directly, but it runs on the hardware and uses hardware resources. Similar to hardware vendors, software developers also are always on the lookout for ways to consume less power. How? Let's take a look. One of the important parts of hardware is the CPU. The CPU can manage self-power consumption with C-States. For those who not familiar yet with C-States, here is a short explanation. C0 -- active state. CPUs have additional C-States, but they are not critical for this article. The following image compares C-states with power consumptions and latency: As you can see, C3 (sleep) is the most power-efficient state. That is, the most power-efficient application is an application that is not launched.an application does nothing and consumes nothing. Of course, an application that does nothing, serves no purpose. The best practical option is an application that works (consumes power) only when it really needs to do something. And when it does do something, it does it as fast as possible. This is very important for applications that work in background mode. Background applications should sleep as long as possible and wake up only when there is something to do. Event-driven softwareHere is example of "incorrect" code. This code reads data from socket and passes it to some handler function. while(true) { // Read data result = recv(serverSocket, buffer, bufferLen, 0); // Handle data if(result != 0) { HandleData(buffer); } // Sleep and repeat Sleep(1000); } What is wrong with this code? The problem is the socket needs data to read or not this code will not work. This affects CPU power consumption. Even if there is nothing to do, the code will periodically wake up the CPU, which consumes power. "Good" code will never wake up anyone, and will never ask every 1000 ms (or some other interval) if there is something to do. "Good" code will "sleep" until something interesting happens. Every operating system has mechanisms for this, like synchronization objects, events, mutexes, and so on. The following code example rewrites this code to use events. Note that it is not incomplete (no error handling)--it only demonstrates the principles of event driven software. WSANETWORKEVENTS NetworkEvents; WSAEVENT wsaSocketEvent; wsaSocketEvent = WSACreateEvent(); WSAEventSelect(serverSocket, wsaSocketEvent, FD_READ|FD_CLOSE); while(true) { // Wait until data will be available in the socket WaitForSingleObject(wsaSocketEve nt, INFINITE); // Read data result = recv(serverSocket, buffer, bufferLen, 0); // Handle data if(result != 0) { HandleData(buffer); } }This code will "sleep" if there is nothing to do. No data in the socket - no activity. Events are a great method for developing power-efficient software, but in some cases we need to do something periodically (for example to play animations or play sound and video). This is where timers come in. TimersLet's say you want your application do something every 40 ms. If you set your timer with a 40 ms interval, the first two intervals (15.6 ms and 31.2 ms) are too early, and procedure with execute at third interval of 46.8 ms. In most cases, the additional 6.8 ms will not matter. This affects not only timer functions, but also the Sleep() function. For example if you call Sleep(10), in case if Windows timer resolution set to default 15.6 ms, you code will "sleep" not 10 ms but 15.6 ms. This is not a problem in most cases, but can be a big problem for time critical applications. For example, this could be a problem for video players or for applications that use animations. In the best-case scenario, an application would adjust the system timer resolution using the timeBeginPeriod() function from the Windows Multimedia API*. This function allows a developer to reduce the timer resolution to as low as 1ms (TIP: To get the minimal available resolution call the timeGetDevCaps() function). This is good for application performance, but bad for battery life, and could drain your battery as much as 25% faster
Finding the compromise is simple to describe, but not always so easy to implement. Adjust the system timer resolution only if you really need a shorter interval (for example, if video or animation is playing), and restore it to default if an application is in idle state, minimized, the device lid is closed, or the display is turned off. Another good practice is to not to change timer resolution if the mobile device is on battery. The Opera and Chrome browsers are a good example of this best practice. For a user perspective on how to extend the battery life, use the Powercfg utility from Microsoft. Using this utility you will locate power-related problems, find out which drivers do not support power ef- 3ficient modes, and see what applications adjust system timer resolution. Timers CoalescingWindows 7 brings a new feature for developers of power-efficient software called timers coalescing. Here is an example of how it works.
Timer coalescing is the ability of the Windows kernel to group multiple software timers from different applications and device drivers and expire them all at the same time. When you combine timer coalescing with the platform timer interrupt distribution improvements in Windows 7, timer coalescing further helps increase the idle duration of the APs. This helps save processor and platform power by waking each AP only when it needs to perform the work for multiple software timers. After that work is complete, the processor returns to a low-power idle state for an extended period of time.
To use this feature you need to setup your timer with
BOOL WINAPI SetWaitableTimerEx( __in HANDLE hTimer, __in const LARGE_INTEGER *lpDueTime, __in LONG lPeriod, __in_opt PTIMERAPCROUTINE pfnCompletionRoutine, __in_opt LPVOID lpArgToCompletionRoutine, __in_opt PREASON_CONTEXT WakeContext, __in ULONG TolerableDelay );
Do This as Quickly as PossibleOne more way to develop power-efficient software is to "teach" your application how to do things faster. You can do this by using hardware optimizations like SSE, AVX and others. For instance, by using the Quick Sync feature of the Sandy Bridge platform you can boost your code, and encode / decode video 10 x times faster. Here is comparison chart, including Quick Sync, at Tom's Hardware. After optimizing the software, you will need to understand how the optimizations affect power efficiency. Here are some valuable tools that you can use:Tools
Learn moreJoin the Ultrabook(TM) developer community.Access technical content, knowledge, and tools to optimize software for the performance, graphics, and power capabilities of Ultrabook devices, then get your app to market through the Intel AppUpp(SM) center and affiliate app stores. Intel Software NetworkIntel AppUp(SM) developer program |