Оценка производительности Android-приложений

Автор: Tuan H. Bui

Обзор

Для оптимизации приложения в целях достижения наилучшего пользовательского опыта важно понимать необходимый уровень производительности, необходимый приложению в рамках конкретной платформы. На операционной системе Linux можно использовать vmstat для отслеживания многих аспектов производительности, в частности, памяти, требований CPU и IO. Менеджер задач Windows* обеспечивает схожие возможности для операционной системы Windows*. А мы обсудим то, как можно добиться подобных показателей продуктивности на операционной системе Android*.

 

 

Изучение вопроса

По существу, Android* – это операционная система Linux*, которая, соответственно, предоставляет схожие показатели продуктивности. Погружение в эти показатели представляется в некоторой степени сложным, поскольку модель эксплуатации телефона или планшета подразумевает выполнение только одного приложения в активном режиме.

Первой задачей в отслеживании производительности приложения, выполняемого на Android*, становится выполнение инструментов мониторинга производительности в процессе работы приложения с нужной нам нагрузкой. Например, мы хотим отследить производительность приложения-проигрывателя видео, чтобы понять, почему оно не работает на требуемом уровне частоты кадров. Так как наше приложение (в этом случае, видеоплеер) выполняется в активном режиме, необходимо искать альтернативный путь для отслеживания производительности в процессе работы плеера. Один из путей обхода – разработать Android-сервис, который будет непрерывно выполняться в фоновом режиме и записывать показатели производительности в файл, который, в свою очередь, можно будет изучить позднее. Еще более простой способ – использовать инструмент Android* Debug Bridge (ADB). Android ADB предоставляет оболочку отладки для операционной системы Android* через USB-кабель или порт TCP/IP. Используйте следующую процедуру для запуска отладки ADB через TCP/IP.

 

 

  1. Разрешите отладку USB на контрольной панели Android*
  2. Присоедините устройство к хосту через USB-кабель. Если вы используете хост Windows*, вам, вероятно, понадобится драйвер USB от поставщика устройства. Хост Linux* обычно не требует специального драйвера.
  3. Убедитесь, что устройство распознается хостом, инициировав команду 'adb devices'. В ответ на команду должен появиться список присоединенных устройств.
  4. Разрешите отладку TCPIP с помощью команды 'adb tcpip 5555'. Эта команда отдает указания adb сделать перезапуск и ожидать от порта 5555 сообщения о соединении.
  5. Отсоедините USB-кабель и снова соединитесь с устройством через команду 'adb <device_ip_address>'.

Присоединившись через ADB, пользователь получает доступ к командной оболочке Unix, которую можно использовать для выполнения различных фоновых мониторинговых команд (вроде 'top' и 'vmstat'), пока приложение работает на основном экране устройства. Имейте в виду, выполнение других команд параллельно с приложением может ухудшить производительность приложения. К примеру, команда 'top' обладает высокой интенсивностью для CPU и должна использоваться осторожно. Наилучшим подходом к отслеживанию производительности с минимальными издержками является регулярный сбор данных, которые уже произвела ОС, и их хранение в файле для дальнейшей обработки после остановки приложения. Android, как и Linux, предлагает много статистики по производительности в файловой системе /proc. Необходимые данные по производительности хранятся в /proc/stat. Для отслеживания производительности системы в регулярном интервале 5 секунд просто используйте схожий скрипт оболочки:



 

while :
do
	echo Date: `date +”%Y-%m-%d %H:%M:%S”`
	cat /proc/stat >> /data/local/tmp/myvmstat.out
	sleep 5
done

 


Ниже два образца proc/stat в пятисекундном интервале, зафиксированные в процессе проигрывания видеоролика 720p H264 в Android Media Player на планшете Motorola Xoom. Для удобства данные были импортированы в таблицу.



В /proc/stat включено множество данных. Наиболее важная информация находится в первой строке, демонстрируя сумму показателей CPU. Каждая последующая строка начинается с показателей ‘cpuN’ для каждого CPU в отдельности. Мы можем видеть, что устройство, представленное в образце, имеет два процессора. Значение для каждой ячейки объясняется ниже:



Единицы времени даны в USER_HZ, обычно в сотых долях секунды. Численные значения в этой статистике носят совокупный характер, начиная с момента последней перезагрузки системы. Для получения данных по производительности за каждый интервал времени, нужно вычислить разницу между данными, зафиксированными в начали в конце каждого интервала.  


 

User: время, потраченное на исполнение процессов в пользовательском режиме
Nice: время, потраченное на исполнение процессов в пользовательском режиме «niced». Под niced-процессами понимаются процессы, выполняемые в приоритете, отличном от приоритета по умолчанию.
System: время, потраченное на исполнение в режиме ядра или в управляющем режиме.
Idle: время простоя. Процесс не выполняются.
Iowait: время ожидания до завершения IO
Irq: время обслуживания прерываний
Softirq: время обслуживания softIRQ
Steal, GuestTime, GuestNiceTime: время, потраченное в виртуальной OS. Обычно эти показатели в Android равны 0.

Оставшиеся данные, представленные в /proc/stats, описаны ниже:



 

Intr: число прерываний системы. Первая колонка после тега ‘intr’ – это общее число прерываний с момента последней перезагрузки. Значения в последующих колонках отображают количество прерываний по номеру, начиная с прерывания 0.
Ctxt: число переключений контекста с последней перезагрузки системы.
Btime: время загрузки системы, представляемое как отсчет в секундах с 1 января 1970 GMT.
Processes: число процессов, инициированных системой с момента перезагрузки.
Procsrunning: число выполняемых процессов.
Procsblocked: процессы, заблокированные до завершения IO.
Softirq: общее число обработанных softirq. SoftIRQ – не критичные по времени прерывания. 


 

Таблица ниже демонстрирует разницу между двумя представленными образцами данных. Колонка суммы показывает общее число временных единиц, затраченных в различных задачах. Колонка CPU Util – это сумма всех задач, не находящихся в состоянии простоя. Строка ниже каждого CPU показывает те же данные в процентном отношении к общему затраченному времени. Обратите внимание, что общее затраченное время в различных задачах прибавляет до 5 секунд. Поскольку в системе 2 процессора, то общее доступное время CPU для каждого из образцов составляет 2x5 = 10 секунд.



Для резонно длительных видов загрузки, таких, как, например, проигрывание видео, мы можем сформировать хронограмму, демонстрирующую задействование рабочих объемов CPU во времени. Изучение такой временной диаграммы позволяет идентифицировать различные фазы, где рабочая нагрузка могла чрезмерно истощать ресурсы процессора. Рис. 1 показывает такую хронограмму для графико-ориентированной рабочей нагрузки. Мы видим, что максимальное использование CPU, достигнутое в рабочей нагрузке, составляет только 50%. Это признак того, что при такой загрузке мог использоваться только один CPU. Если бы было важным ускорить эту рабочую нагрузку, было бы целесообразным найти пути для использования второго CPU.



Рис. 1 - An3DBenchXLCPUUtilization

Использование CPU не дает полной картины производительности. Современные процессоры обычно могут работать с несколькими частотами (pstates). Операционная система может менять частоту процессора для минимизации энергопотребления и сохранения заряда батареи в случае с мобильными устройствами.

Рис. 2 демонстрирует использование CPU наряду со средней рабочей частотой процессора на одном и том же планшете при проигрывании одного и того же видео, закодированного под с разрешением 720p H264 и 360p H264. Как показывают данные, проигрывание видео 720p H264 требует более интенсивного расходования ресурсов. Декодирование видео 720p H264 не только требует в 4 раза большего уровня использования CPU, но также работы процессора на частоте в 2,4 раза выше.

 

Рис. 2 – Производительность при проигрывании видео

Android сообщает о рабочей частоте процессора (pstate) в файле the/sys/devices/system/cpu/cpuX/cpufreq/stats/time_in_state. Скрипт, представленный ниже, модифицирован с целью включения pstate-данных по процессору. 


 

while :
do
	echo Date: `date +”%Y-%m-%d %H:%M:%S”`
	cat /proc/stat >> /data/local/tmp/myvmstat.out
	echo CPU0 Pstate Residency
	cat /sys/devices/cpu/cpu0/cpufreq/stats/time_in_state
	echo CPU1 Pstate Residency
	cat /sys/devices/cpu/cpu1/cpufreq/stats/time_in_state
	sleep 5
done


Данные, полученные из pstate-информации о процессоре для Motorola Xoom, представлены ниже:

 

CPU0 PState Residency
216000 4356448
312000 400626
456000 559897
608000 398231
760000 92081
816000 0
912000 0
1000000 1485891


Каждая пара данных представляет собой частоту pstate в КГц, а также количество времени в сотых секунды, проведенного в этом режиме после перезагрузки системы. Число доступных частот pstate отличается для каждого процессора. В этом случае процессор NVIDIA Tegra2 в Motorola Xoom обеспечивает 8 различных частот – от 216 МГц до 1ГГц.

Используя эту технику для измерения нагрузки CPU, мы можем рассчитать процентное соотношение времени, затраченного процессором в каждой частоте в данном конкретном интервале. Также мы можем получить среднюю частоту для одного и того же интервала путем подсчета взвешенной суммы частот и процентного соотношения затраченного времени. Подобные данные были получены и показаны на Рис. 1. 

 

 

 Выводы

Используя ADB и существующую инфраструктуру производительности, которую Android* унаследовал от Linux*, мы можем получить глубокое понимание характеристик производительности Android-приложения. Эти выводы могут быть использованы для оптимизации пользовательского опыта и снижения энергопотребления.

 

 

ВложениеРазмер
Иконка изображения playback-perfomance.jpg69.25 КБ
Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.
Возможность комментирования русскоязычного контента была отключена. Узнать подробнее.