Для оценки производительности устройства используйте Simpleperf. Simpleperf – это встроенный инструмент профилирования для приложений и нативных процессов в Android. Используйте профилировщик ЦП, чтобы отслеживать использование ЦП приложением и активность потоков в реальном времени.
Пользователи могут видеть два показателя производительности:
- Предсказуемая и заметная эффективность. Пропускает ли пользовательский интерфейс кадры или постоянно отрисовывает 60 кадров в секунду? Воспроизводится ли звук без артефактов и щелчков? Какова задержка между касанием экрана и появлением эффекта на дисплее?
- Время, необходимое для выполнения более длительных операций (например, открытия приложений).
Первый вариант более заметен, чем второй. Пользователи обычно замечают рывки, но не могут отличить время запуска приложения в 500 мс от 600 мс, если только не сравнивают два устройства рядом. Задержка касания сразу заметна и значительно влияет на восприятие устройства.
Поэтому в быстром устройстве конвейер интерфейса является самым важным элементом системы, за исключением того, что необходимо для его работы. Это означает, что конвейер интерфейса должен иметь приоритет над любой другой работой, которая не является необходимой для плавного отображения интерфейса. Чтобы интерфейс работал без сбоев, фоновая синхронизация, доставка уведомлений и другие подобные задачи должны откладываться, если можно запустить задачу интерфейса. Допустимо снизить производительность более длительных операций (например, HDR+, запуск приложения и т. д.), чтобы обеспечить плавную работу интерфейса.
Пропускная способность и джиттер
При оценке производительности устройства важными показателями являются пропускная способность и джиттер.
Размер
Емкость – это общий объем ресурса, которым устройство располагает за определенный период времени. Это могут быть ресурсы ЦП, графического процессора, I/O, сети, пропускная способность памяти или любой другой подобный показатель. При анализе производительности всей системы может быть полезно абстрагироваться от отдельных компонентов и использовать один показатель, определяющий производительность (особенно при настройке нового устройства, поскольку рабочие нагрузки, выполняемые на этом устройстве, скорее всего, фиксированы).
Производительность системы зависит от доступных вычислительных ресурсов. Изменение частоты ЦП/ГП – основной способ изменения производительности, но есть и другие, например изменение количества ядер ЦП в сети. Таким образом, мощность системы соответствует энергопотреблению: изменение мощности всегда приводит к аналогичному изменению энергопотребления.
Требуемая в определенный момент времени мощность в основном зависит от запущенного приложения. В результате платформа может мало что сделать, чтобы скорректировать мощность, необходимую для определенной рабочей нагрузки. Средства для этого ограничены улучшениями среды выполнения (платформа Android, ART, Bionic, компилятор/драйверы графического процессора, ядро).
Дрожание
Если необходимую емкость для рабочей нагрузки определить легко, то джиттер – понятие более туманное. Чтобы лучше понять, как джиттер влияет на производительность систем, рекомендуем прочитать статью The Case of the Missing Supercomputer Performance: Achieving Optimal Performance on the 8,192 processors of ASCI Q (Почему суперкомпьютеры не работают на полную мощность: как добиться оптимальной производительности 8192 процессоров ASCI Q). (В нем рассказывается о том, почему суперкомпьютер ASCI Q не достиг ожидаемой производительности, и дается отличное введение в оптимизацию больших систем.)
В этой статье используется термин "джиттер", который в документе ASCI Q называется шумом. Джиттер – это случайное поведение системы, которое не позволяет выполнять заметную работу. Часто это задачи, которые необходимо выполнить, но у них нет строгих требований к времени выполнения. Поскольку дрожание носит случайный характер, доказать его отсутствие для определенной рабочей нагрузки крайне сложно. Кроме того, крайне сложно доказать, что известный источник дрожания был причиной конкретной проблемы производительности. Инструменты, которые обычно используются для диагностики причин дрожания (например, трассировка или ведение журнала), могут сами вызывать дрожание.
Источники джиттера, возникающего в реальных реализациях Android, включают:
- Задержка планировщика
- Обработчики прерываний
- Код драйвера выполняется слишком долго при отключенном вытеснении или прерываниях
- Долго выполняющиеся softirq
- Конфликт блокировок (приложение, фреймворк, драйвер ядра, блокировка binder, блокировка mmap).
- Конфликт дескрипторов файлов, при котором низкоприоритетный поток удерживает блокировку файла, не позволяя выполняться высокоприоритетному потоку.
- Выполнение критически важного для интерфейса кода в рабочих очередях, где он может быть задержан.
- Переходы ЦП в режим ожидания
- Журналы
- Задержки ввода-вывода
- Создание ненужных процессов (например, трансляций
CONNECTIVITY_CHANGE). - Перегрузка кеша страниц из-за недостатка свободной памяти
Требуемое время для определенного периода джиттера может уменьшаться или не уменьшаться с увеличением емкости. Например, если драйвер оставляет прерывания отключенными, ожидая чтения из шины i2c, это займет фиксированное количество времени независимо от того, работает ли ЦП на частоте 384 МГц или 2 ГГц. Увеличение пропускной способности не поможет повысить производительность, если есть дрожание. В результате более быстрые процессоры обычно не улучшают производительность в ситуациях, когда ограничено дрожание.
Наконец, в отличие от пропускной способности, дрожание почти полностью находится в сфере ответственности поставщика системы.
Потребление памяти
Обычно в низкой производительности винят потребление памяти. Само по себе потребление памяти не является проблемой производительности, но может вызывать дрожание из-за избыточных расходов lowmemorykiller, перезапуска служб и переполнения кеша страниц. Уменьшение потребления памяти может помочь избежать прямых причин низкой производительности, но есть и другие способы, например закрепление фреймворка, чтобы он не выгружался из памяти, когда вскоре понадобится снова.
Как анализировать первоначальную производительность устройства
Если вы начнете с работающей, но неэффективной системы и попытаетесь исправить ее поведение, рассматривая отдельные случаи низкой производительности, заметной для пользователей, это не будет разумной стратегией. Поскольку низкая производительность обычно трудно воспроизводима (например, из-за дрожания) или связана с проблемами в приложении, слишком много переменных в полной системе не позволяют этой стратегии быть эффективной. В результате очень легко ошибиться в определении причин и внести незначительные улучшения, упустив при этом системные возможности для исправления производительности во всей системе.
Вместо этого при настройке нового устройства следуйте приведенным ниже общим рекомендациям.
- Загрузите систему в интерфейс с запущенными драйверами и основными настройками регулятора частоты (если вы измените настройки регулятора частоты, повторите все описанные ниже шаги).
- Убедитесь, что ядро поддерживает точку трассировки
sched_blocked_reason, а также другие точки трассировки в конвейере отображения, которые указывают, когда кадр доставляется на дисплей. - Сделайте длинные трассировки всего конвейера пользовательского интерфейса (от получения входных данных через IRQ до окончательного сканирования), выполняя легкую и стабильную рабочую нагрузку (например, UiBench или тест с шариком в TouchLatency).
- Устраните пропуски кадров, обнаруженные при легкой и стабильной рабочей нагрузке.
- Повторяйте шаги 3–4, пока не добьетесь того, чтобы в течение 20 секунд не было пропущено ни одного кадра.
- Перейдите к другим источникам рывков, заметным для пользователей.
На ранних этапах настройки устройства можно выполнить следующие простые действия:
- Убедитесь, что в ядре есть патч для точки трассировки sched_blocked_reason. Эта точка трассировки включается с помощью категории трассировки sched в systrace и предоставляет функцию, ответственную за переход в спящий режим, когда поток переходит в непрерываемый спящий режим. Это важно для анализа производительности, поскольку непрерывный сон – очень распространенный признак дрожания.
- Убедитесь, что у вас достаточно данных трассировки для конвейеров GPU и дисплея. На новых чипсетах Qualcomm tracepoint включаются с помощью следующей команды:
adb shell "echo 1 > /d/tracing/events/kgsl/enable"adb shell "echo 1 > /d/tracing/events/mdss/enable"
Эти события остаются включенными при запуске systrace, поэтому в разделе mdss_fb0 можно увидеть дополнительную информацию о конвейере дисплея (MDSS). На однокристальных системах Qualcomm в стандартном представлении systrace не будет дополнительных сведений о графическом процессоре, но результаты будут в самой трассировке (подробнее об этом рассказывается в статье Как работать с systrace).
Вам нужно одно событие, которое напрямую указывает, что кадр был доставлен на экран. Это позволит вам определить, уложились ли вы во время формирования кадра.Если событие Xn происходит менее чем через 16,7 мс после события Xn-1 (при частоте обновления экрана 60 Гц), то задержки не было. Если ваш SOC не предоставляет такие сигналы, обратитесь к поставщику. Отладка дрожания чрезвычайно сложна без определенного сигнала о завершении кадра.
Используйте синтетические тесты
Синтетические тесты полезны для проверки основных функций устройства. Однако не стоит использовать тесты в качестве показателя воспринимаемой производительности устройства.
Опыт работы с SoC показывает, что разница в производительности синтетических тестов между SoC не коррелирует с аналогичной разницей в заметной производительности интерфейса (количество пропущенных кадров, время формирования кадра на 99-м процентиле и т. д.). Синтетические тесты производительности оценивают только емкость. Джиттер влияет на результаты таких тестов, только если он отнимает время у массовых операций. В результате синтетические тесты производительности в основном не имеют отношения к показателям производительности, воспринимаемой пользователем.
Предположим, что два процессора выполняют тест Benchmark X, который отрисовывает 1000 кадров интерфейса и сообщает общее время отрисовки (чем ниже показатель, тем лучше).
- SOC 1 обрабатывает каждый кадр Benchmark X за 10 мс и получает оценку 10 000.
- SOC 2 формирует 99% кадров за 1 мс, а 1 % – за 100 мс, и получает оценку 19 900, которая значительно лучше.
Если бы тест отражал реальную производительность интерфейса, SOC 2 был бы непригоден для использования. При частоте обновления 60 Гц SOC 2 будет пропускать кадр каждые 1, 5 секунды работы. При этом на однокристальной системе 1 (более медленной по результатам теста X) все будет работать плавно.
Как использовать отчеты об ошибках
Отчеты об ошибках иногда полезны для анализа производительности, но из-за их большого размера они редко помогают при отладке спорадических проблем с задержками. Они могут содержать подсказки о том, что делала система в определенный момент времени, особенно если рывки происходили при переходе между приложениями (что регистрируется в отчете об ошибке). Отчеты об ошибках также могут указывать на более серьезные проблемы с системой, которые могут снизить ее эффективную емкость (например, перегрев или фрагментация памяти).
Как использовать TouchLatency
Несколько примеров некорректного поведения взяты из TouchLatency – предпочтительной периодической рабочей нагрузки, используемой для Pixel и Pixel XL. Он доступен по адресу frameworks/base/tests/TouchLatency и имеет два режима: "Задержка сенсорного ввода" и "Прыгающий мяч" (чтобы переключиться между ними, нажмите кнопку в правом верхнем углу).
Тест с прыгающим мячом очень прост: мяч бесконечно прыгает по экрану, независимо от действий пользователя. Обычно это самый сложный тест, но чем меньше кадров будет пропущено, тем лучше. Тест с прыгающим мячом сложен, поскольку это тривиальная, но идеально согласованная рабочая нагрузка, которая выполняется на очень низкой тактовой частоте (предполагается, что устройство имеет регулятор частоты; если вместо этого устройство работает с фиксированными тактовыми частотами, уменьшите тактовую частоту ЦП/графического процессора до околоминимальной при первом запуске теста с прыгающим мячом). По мере того как система переходит в режим ожидания и тактовая частота снижается, время, необходимое ЦП и графическому процессору на обработку кадра, увеличивается. Вы можете следить за мячом и заметить, что изображение дергается. Кроме того, пропущенные кадры можно увидеть в systrace.
Поскольку рабочая нагрузка постоянна, вы можете легко определить большинство источников дрожания, отслеживая, что именно выполняется в системе во время каждого пропущенного кадра, а не конвейер интерфейса. Более низкая частота тактового сигнала усиливает эффект дрожания, поскольку при этом с большей вероятностью будет пропущен кадр. Чем ближе значение TouchLatency к 60 кадрам в секунду, тем меньше вероятность возникновения проблем с системой, которые приводят к случайным, трудно воспроизводимым рывкам в крупных приложениях.
Поскольку джиттер часто (но не всегда) не зависит от тактовой частоты, для его диагностики используйте тест, который выполняется на очень низкой тактовой частоте. Это необходимо по следующим причинам:
- Не все колебания не зависят от тактовой частоты. Многие источники просто потребляют время процессора.
- Контроллер должен снизить частоту, чтобы среднее время формирования кадра было близко к предельному, поэтому время, затраченное на выполнение задач, не связанных с интерфейсом, может привести к пропуску кадра.