Windows 7: Разработка энерго-эффективных приложений
Никому из нас не нравится, когда не вовремя садится аккумулятор мобильного телефона или компьютера. Ни для кого не секрет, что новая версия Windows 7, которая недавно стала доступна для скачивания MSDN подписчикам, позволяет создавать энергоэффективные приложения. Статья позволит узнать Windows разработчикам новые полезные методы, техники и средства, которые помогут увеличить время работы мобильных устройств.
Энергопотребление
Давайте для начала посмотрим на тенденцию развития современных вычислительных процессоров. Исследователи лаборатории Microsoft Research проанализировали множество параметров современных процессоров (количество транзисторов, мощность, производительность и т.д.). Особое внимание обращалось на потребляемую мощность процессоров. Ниже представлен обзор процессоров Intel за последние 20 лет.
Как мы видим, согласно исследованиям Microsoft Research, количество потребляемой энергии процессорами стремительно растет. Процессор Intel 80386SX почти не потребляет энергии, но и не обладает высокой производительностью. Если мы посмотрим на топ процессоры последних лет, обладающие высокой производительностью, Core 2 Extreme QX6700 и другие, то становится очевидным, какое большое количество энергии потребляют эти процессоры (около 100Вт). Данная тенденция наблюдается не только у современных процессоров, но и у многих других комплектующих современных компьютеров (GPU, Ethernet и т.д.), что становится серьезной проблемой.
Если изучить проблему глубже, причиной высокого потребления энергии являются не только комплектующие (Процессор, GPU, Ethernet) и операционная система, но и дополнительное программное обеспечения. Команда разработчиков Windows 7 сравнила продолжительность работы компьютера от батареи при чистой установке и с предустановкой программного обеспечения OEM производителей.
Налицо большой разброс значений, но в большинстве случаев чистая установка позволяет компьютеру работать от батареи дольше. Отсюда мы можем сделать вывод – разрабатываемые нами приложения оказывают сильное влияние на энергопотребление нашего устройства. Энергоэффективное приложение позволит увеличить время работы мобильного устройства, например, ноутбука, и сократить расходы на электроэнергию в случаи серверной станции.
Разработки в области энергоэффективных решений
Энергопотребление стремительно растет, что вызывает активные разработки в данном направлении. Одна из них концепция “Батарея на весь день”, которая позволит использовать мобильные устройства 6,9 и более часов. Таким образом, мы сегодня говорим о тех возможностях, которые мы можем использовать для увеличения времени работы нашего мобильного устройства от батареи. Многие OEM производители ведут разработки в области энергоэффективных устройств. Мы можем наблюдать тенденции по оптимизации решений не только для мобильных устройств, но и для десктоп, и серверных станций. Компании хотят сократить энергопотребление их офисов и дата центров. Сегодня я хотел поговорить о методах разработки именно таких энергоэффективных приложений и о средствах диагностики решений, которые помогут сделать эти приложения лучше.
Схема разработки энергоэффективного приложения
1) Осознать причины высокого энергопотребления
2) Понизить использование ресурсов
3) Обратить внимание на простой
4) Адаптировать программное обеспечение под системное окружение
5) Использовать правильные средства и технологии
6) Обратить внимание в приложении на изменение состояний ОС (рестарт, завершение работы, сон и т.д.)
7) Проверить с помощью средств диагностики
8) Повторить все заново (вернуться к шагу 2)
Обратим внимание на простой
Когда мы говорим о продолжительности работы мобильного устройства от батарейки, важно обратить внимание на тип работы. 2 часа просмотра DVD? 2 часа офисной работы или 2 часа простоя? В каждом из случаев устройство расходует разное количество энергии. Но важно то, что все они связаны с простоем. В режиме простоя процессор расходует малое количество энергии. Поэтому главной задачей является, наибольшее сокращение расхода энергии на базовом слое ”Простое”.
Сократить потребление энергии можно, выполняя какие-то операции менее часто или отрисовывая меньшее количество графики. Хорошим примером является цветовая схема в Windows Vista. При переходе в режим “Power saver”, Windows меняет цветовую схему на более простую (не прозрачную), позволяю компьютеру работать чуть дольше. Другим примером является то, как команда оптимизировала проигрывание DVD в Windows 7. Скорость проигрывания была уменьшена с 60fps до 30fps. Для пользователя данное изменение не заметно, но, представьте, насколько меньше потребляет теперь наша система.
Другой метод уменьшения потребления энергии – оптимизация кода, которая позволяет на каждом этапе добавить лишнее время работы от аккумулятора. Все эти техники являются инструментом сокращения количества потребляемой энергии в режиме работы процессора.
Еще одним трюком уменьшения потребления энергии является метод, при котором мы пытаемся выполнить нашу работу, как можно быстрее, тем самым, попадая в состояния простоя на максимально возможное количество времени. Т.е. мы пытаемся находиться в состоянии простоя, как можно чаще и как можно дольше. Порой выгоднее подняться на более высокий уровень потребления энергии, выполнить задачу, как можно быстрее и вернуться в состояние простоя. Хорошим примером является менеджер управления питанием процессора в Windows, который сильно пульсирующий.
Техники оптимизации
Если мы посмотрим на современные мобильные процессоры, то увидим, что они обладают большим динамическим диапазоном потребляемой мощности. Они практически ничего не потребляют в режиме простой, с другой стороны они съедают большое количество энергии при предельной производительности. Поэтому очень важно сфокусироваться на простое!
Использование процессора
Исключите в своих программах опросы, используйте события! В Vista и более новых версиях ОС существует специальный API (RegisterPowerSettingNotification), построенный на событиях, которые позволяют отслеживать состояние питания вашего устройства (См. код ниже). В примере я использую Windows API Code Pack for .Net Framework. Пример работающего приложения можно закачать по ссылке в конце поста.
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
PowerManager.PowerSourceChanged += new EventHandler(PowerManager_PowerSourceChanged);
}
private void PowerManager_PowerSourceChanged(object sender, EventArgs e)
{
lab1.Content = PowerManager.PowerSource;
}
}
В случае если опрос в вашей программе всё-таки необходим, постарайтесь делать его, как можно реже. Я рекомендую вам воспользоваться новым Объединяющим программным интерфейсом (Сoalescing API), который позволяет увеличить интервалы простоя.
Когда команда разрабатывала Windows 7, она обратила внимание на то, что многие системные процессы имеют периодический характер. Хорошим примером является Диспетчер питания процессора, который изменяет напряжение на процессоре, тем самым, регулируя вычислительную мощность. Он изменяет напряжение процессора на основании данных о предыдущем состояние, и для этого он использует периодический опрос.
Еще раз повторюсь, современные процессоры потребляют невероятно малое количество энергии в режиме простоя. И нашей главное задачей является – сделать так, чтобы процессор находился в этом состоянии, как можно дольше. Хочу обратить ваше внимание на то, что на смену режима процессор расходует дополнительную энергию. Поэтому не исключен вариант, когда вы потратите больше энергии на переключения, чем сохраните в режиме простоя. В связи с этим нам требуется находиться в режиме простоя, как можно дольше.
Windows timer coalescing API
Идея Сoalescing API в объединении повторяющихся активностей. На графике снизу представлен пример активностей в системе (нереальные данные). Как мы видим, на графике Windows управляется периодическим таймером, который выполняется раз в 15.6 мс +. У нас в системе происходят периодически события по таймеру, этих событий много, и они разбросаны случайным образом по временной оси. Новый API позволяет их группировать, обеспечивая состояние простоя максимально продолжительный период времени.
Вы можете применить данную возможность в приложениях и сервисах, используя функцию пользовательского уровня SetWaitableTimerEx. Тем не менее, я рекомендую использовать события. Если же вы не можете отказаться от периодических таймеров, “Windows timer coalescing API”поможет вам сделать это наиболее эффективно.
Прототип функции SetWaitableTimerEx:
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
);
ФункцияSetWaitableTimerEx очень похожа на функцию SetWaitableTimer, которая используется для определения периода, за который таймер должен истекать. Во многих ситуациях можно просто заменить функцию SetWaitableTimerна SetWaitableTimerEx. У SetWaitableTimerExпоявились два новых параметра: WakeContext и TolerableDelay. Параметр WakeContextнужно использовать только, если вы хотите установить таймер, который может вывести систему из состояния сна. Параметр TolerableDelay определяет допустимое отклонение от заданного временного интервала в мс.
Вы должны использовать значение не меньшее чем 32 мс (2 интервала прерывания platform timer’а) для параметра TolerableDelay. Оптимально, когда значение допустимого отклонения увеличивается вместе со значением интервала. Например, если период между прерываниями равен 1ой секунде, то подходящее значение отклонения будет равно 50 мс. Тем не менее, если длина периода равна 30 секундам, значение отклонения должно быть не менее 1,000 мс.
Таблица требований функции SetWaitableTimerEx.
SetWaitableTimerEx требования |
|
Header |
Winbase.h |
Library |
Kernel32.lib |
DLL |
Kernel32.dll |
Поддерживаемые ОС |
Windows 7 или Windows Server 2008 R2 или более новые |
Практика использования
Вы должны использовать “Windows Timer Coalescing API” для оптимизации энергопотребления ваших приложений и драйверов устройств. Тем не менее, группирование активностей не может заменить разумного использования ресурсов. В первую очередь нужно постараться ограничить периодическую активность в приложении и постараться использовать модель событий.
Когда вы используете “Windows Timer Coalescing API”, обратите внимание:
· Период между прерываниями не гарантирован. Однако он всегда выполняется с учетом погрешности (TolerableDelay).
· Используйте значение параметра TolerableDelay не менее 32 мс, что соответствует двум прерываниям platform таймера, которое происходит каждые 15.6 мс.
· Используйте в качестве значения параметра TolerableDelayзначение кратное 50, например50,100, 250, 500 мс и т.д.
[DllImport("kernel32.dll")]
static extern bool SetWaitableTimerEx(IntPtr hTimer, [In] ref long ft, int lPeriod, TimerCompleteDelegate pfnCompletionRoutine, IntPtr pArgToCompletionRoutine, bool fResume, REASON_CONTEXT wakeContext, ulong tolerableDelay);
Пример, использующий данную технологию, можно скачать в конце поста.
Жесткий диск
Современные жесткие диски потребляют около 8% энергии от общего потребление, и поэтому очень важно обратить внимание на все дисковые активности в вашей системе. Как мы видим на графике, наиболее ресурсоемкими являются операции чтения и записи, для достижения которых диску нужно раскрутиться и потратить много энергии. Используйте жесткий диск только тогда, когда это действительно требуется, постарайтесь исключить все периодические дисковые активности.
Изменение состояния
В Windows 7 команда разработчиков сделал новый API, который позволяет им не только сохранять состояние компьютера (пример Media Center, который позволяет часами проигрывать видео, не уходя в sleep; для этого он постоянно сообщает системе, что ему требуется находиться в рабочем состоянии), но и сообщать, какое приложение, и почему сохраняет или изменяет текущее состояние.
/// Создаем контекст
var powerRequestContext = new POWER_REQUEST_CONTEXT();
powerRequestContext.Version = POWER_REQUEST_CONTEXT_VERSION;
powerRequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
powerRequestContext.SimpleReasonString = "App is doing job";
/// Создаем запрос
IntPtr powerRequest = PowerCreateRequest(ref powerRequestContext);
/// Устанавливаем запрос
PowerSetRequest(powerRequest, PowerRequestType.PowerRequestSystemRequired);
/// Выполняем работу
Console.WriteLine("Press any key");
Console.ReadLine();
/// Очищаем запрос
PowerClearRequest(powerRequest, PowerRequestType.PowerRequestSystemRequired);
Средства диагностики
Команда разработчиков Windows 7 включила в новую версию ОС новые средства для диагностики ваших приложение. Одна из таких утилитов PowerCFG, которую можно вызвать из консоли и получить небольшой отчет о текущем состоянии энергопотребления.
Давай теперь посмотрим полученный HTML.
Данный документ обеспечивает быстрое получение информации и рекомендации к оптимизации о процессах в системе.
Для более подробного анализа стоит воспользоваться пакетом Windows Performance Tools Kit (XPerf), который позволяет получить полный спектр данных по всем параметрам и процессам.
Резюме
Современное программное обеспечение оказывает огромное влияние на потребляемую электроэнергию. Находясь как можно чаще и дольше в простое, мы можем сохранить значительное количество энергии. Надеюсь, данная короткая статья поможет вам лучше понять техники и методы оптимизации вашего приложения с точки зрения энергопотребления.