Используйте Simpleperf для оценки производительности устройства. Simpleperf — это собственный инструмент профилирования как для приложений, так и для собственных процессов на Android. Используйте CPU Profiler для проверки загрузки ЦП приложения и активности потоков в режиме реального времени.
Есть два видимых пользователю индикатора производительности:
- Предсказуемая, ощутимая производительность . Пропускает ли пользовательский интерфейс (UI) кадры или постоянно ли он отображается со скоростью 60 кадров в секунду? Звук воспроизводится без артефактов или хлопков? Какова задержка между прикосновением пользователя к экрану и отображением эффекта на дисплее?
- Продолжительность времени, необходимого для более длительных операций (таких как открытие приложений).
Первое более заметно, чем второе. Пользователи обычно замечают рывки, но они не смогут определить время запуска приложения 500 мс против 600 мс, если они не смотрят на два устройства бок о бок. Задержка касания сразу заметна и значительно влияет на восприятие устройства.
В результате в быстром устройстве конвейер пользовательского интерфейса является наиболее важной частью системы, помимо того, что необходимо для поддержания работоспособности конвейера пользовательского интерфейса. Это означает, что конвейер пользовательского интерфейса должен вытеснять любую другую работу, которая не требуется для гибкого пользовательского интерфейса. Чтобы поддерживать гибкий пользовательский интерфейс, фоновая синхронизация, доставка уведомлений и аналогичная работа должны быть отложены, если работа с пользовательским интерфейсом может быть запущена. Допустимо пожертвовать производительностью более длительных операций (время выполнения HDR+, запуск приложения и т. д.) для поддержания плавного пользовательского интерфейса.
Емкость против джиттера
При рассмотрении производительности устройства емкость и джиттер являются двумя значимыми показателями.
Вместимость
Емкость — это общее количество некоторого ресурса, которым обладает устройство в течение определенного периода времени. Это могут быть ресурсы ЦП, ресурсы графического процессора, ресурсы ввода-вывода, сетевые ресурсы, пропускная способность памяти или любая подобная метрика. При исследовании производительности всей системы может быть полезно абстрагироваться от отдельных компонентов и принять единую метрику, определяющую производительность (особенно при настройке нового устройства, поскольку рабочие нагрузки, выполняемые на этом устройстве, скорее всего, фиксированы).
Емкость системы варьируется в зависимости от вычислительных ресурсов в сети. Изменение частоты процессора/графического процессора является основным способом изменения емкости, но есть и другие способы, такие как изменение количества ядер процессора в режиме онлайн. Соответственно мощность системы соответствует потребляемой мощности; изменение мощности всегда приводит к аналогичному изменению потребляемой мощности.
Емкость, необходимая в данный момент времени, во многом определяется работающим приложением. В результате платформа мало что может сделать для настройки емкости, необходимой для данной рабочей нагрузки, а средства для этого ограничены улучшениями во время выполнения (инфраструктура Android, ART, Bionic, компилятор/драйверы графического процессора, ядро).
Джиттер
В то время как требуемую емкость для рабочей нагрузки легко увидеть, джиттер — более расплывчатое понятие. Хорошее введение в джиттер как препятствие для быстрых систем можно найти в СЛУЧАЕ ОТСУТСТВУЮЩЕЙ ПРОИЗВОДИТЕЛЬНОСТИ СУПЕРКОМПЬЮТЕРА: ДОСТИЖЕНИЕ ОПТИМАЛЬНОЙ ПРОИЗВОДИТЕЛЬНОСТИ НА 8192 ПРОЦЕССОРАХ ASCl Q. (Это исследование того, почему суперкомпьютер ASCI Q не достиг ожидаемой производительности, и отличное введение в оптимизацию больших систем.)
На этой странице термин джиттер используется для описания того, что в документе ASCI Q называется шумом . Джиттер — это случайное поведение системы, препятствующее выполнению ощутимой работы. Часто это работа, которую необходимо выполнять, но она может не иметь строгих требований к времени, которые заставляют ее выполняться в любое конкретное время. Поскольку он является случайным, крайне сложно опровергнуть существование джиттера для данной рабочей нагрузки. Также крайне сложно доказать, что известный источник джиттера был причиной конкретной проблемы с производительностью. Инструменты, наиболее часто используемые для диагностики причин джиттера (например, трассировка или регистрация), могут привносить свой собственный джиттер.
Источники джиттера, наблюдаемые в реальных реализациях Android, включают:
- Задержка планировщика
- Обработчики прерываний
- Код драйвера работает слишком долго с отключенными вытеснением или прерываниями
- Долго работающие программные прерывания
- Конфликт за блокировку (приложение, платформа, драйвер ядра, блокировка связывателя, блокировка mmap)
- Конфликт дескриптора файла, когда поток с низким приоритетом удерживает блокировку файла, предотвращая запуск потока с высоким приоритетом.
- Запуск кода, критичного для пользовательского интерфейса, в рабочих очередях, где он может быть отложен.
- Переходы бездействия ЦП
- логирование
- Задержки ввода/вывода
- Создание ненужного процесса (например, широковещательные рассылки CONNECTIVITY_CHANGE)
- Переполнение кеша страниц из-за нехватки свободной памяти
Требуемое количество времени для заданного периода джиттера может уменьшаться или не уменьшаться по мере увеличения пропускной способности. Например, если драйвер отключает прерывания во время ожидания чтения по шине i2c, это займет фиксированное количество времени, независимо от того, работает ли ЦП на частоте 384 МГц или 2 ГГц. Увеличение пропускной способности не является приемлемым решением для повышения производительности, когда присутствует джиттер. В результате более быстрые процессоры обычно не улучшают производительность в ситуациях с ограничением джиттера.
Наконец, в отличие от пропускной способности, джиттер почти полностью зависит от поставщика системы.
Потребление памяти
Потребление памяти традиционно винят в низкой производительности. Хотя потребление само по себе не является проблемой производительности, оно может вызвать дрожание из-за накладных расходов lowmemorykiller, перезапусков службы и перегрузки кэша страниц. Сокращение потребления памяти может устранить прямые причины низкой производительности, но могут быть и другие целевые улучшения, которые также устраняют эти причины (например, закрепление платформы, чтобы предотвратить ее выгрузку, когда она будет загружена вскоре после этого).
Анализ начальной производительности устройства
Начинать с функциональной, но плохо работающей системы и пытаться исправить поведение системы, рассматривая отдельные случаи заметной пользователю низкой производительности, — неразумная стратегия. Поскольку плохую производительность обычно нелегко воспроизвести (например, дрожание) или это проблема приложения, слишком много переменных во всей системе не позволяют этой стратегии быть эффективной. В результате очень легко неправильно определить причины и внести незначительные улучшения, упустив при этом системные возможности для исправления производительности всей системы.
Вместо этого используйте следующий общий подход при подключении нового устройства:
- Получите загрузку системы в пользовательский интерфейс со всеми запущенными драйверами и некоторыми базовыми настройками регулятора частоты (если вы измените настройки регулятора частоты, повторите все шаги ниже).
- Убедитесь, что ядро поддерживает
sched_blocked_reason
, а также другие точки трассировки в конвейере отображения, которые указывают, когда кадр доставляется на дисплей. - Проведите длинные трассировки всего конвейера пользовательского интерфейса (от получения ввода через IRQ до окончательного сканирования) при выполнении легкой и последовательной рабочей нагрузки (например, UiBench или тест мяча в TouchLatency) .
- Исправьте пропадание кадров, обнаруженное в облегченной и последовательной рабочей нагрузке.
- Повторяйте шаги 3–4 до тех пор, пока вы не сможете работать с нулевым количеством пропущенных кадров в течение 20+ секунд за раз.
- Перейдите к другим видимым пользователям источникам нежелательной почты.
Другие простые вещи, которые вы можете сделать на ранней стадии запуска устройства, включают:
- Убедитесь, что в вашем ядре есть патч точки трассировки sched_blocked_reason . Эта точка трассировки включена с категорией запланированной трассировки в systrace и предоставляет функцию, отвечающую за спящий режим, когда этот поток переходит в непрерываемый спящий режим. Это очень важно для анализа производительности, потому что непрерывный сон является очень распространенным индикатором джиттера.
- Убедитесь, что у вас есть достаточная трассировка для графического процессора и конвейеров отображения. В последних SOC Qualcomm точки трассировки включаются с помощью:
adb shell "echo 1 > /d/tracing/events/kgsl/enable"
adb shell "echo 1 > /d/tracing/events/mdss/enable"
Эти события остаются включенными при запуске systrace, поэтому в трассировке вы можете увидеть дополнительную информацию о конвейере отображения (MDSS) в разделе mdss_fb0
. В SOC Qualcomm вы не увидите никакой дополнительной информации о графическом процессоре в стандартном представлении systrace, но результаты будут представлены в самой трассировке (подробности см. в разделе Общие сведения о systrace ).
То, что вы хотите от такого рода трассировки дисплея, — это одно событие, которое прямо указывает на то, что кадр был доставлен на дисплей. Оттуда вы можете определить, успешно ли вы достигли времени кадра; если событие X n происходит менее чем через 16,7 мс после события X n-1 (при условии, что дисплей 60 Гц), то вы знаете, что не дергали. Если ваш SOC не предоставляет такие сигналы, обратитесь к своему поставщику, чтобы получить их. Отладка джиттера чрезвычайно сложна без окончательного сигнала завершения кадра.
Использование синтетических тестов
Синтетические тесты полезны для проверки наличия базовой функциональности устройства. Однако рассматривать эталонные тесты как показатель воспринимаемой производительности устройства бесполезно.
Исходя из опыта работы с SOC, различия в производительности синтетических тестов между SOC не коррелируют с аналогичной разницей в ощутимой производительности пользовательского интерфейса (количество пропущенных кадров, время кадра 99-го процентиля и т. д.). Синтетические тесты — это тесты только для емкости; джиттер влияет на измеренную производительность этих тестов только за счет кражи времени у основной операции теста. В результате результаты синтетических тестов в большинстве случаев не имеют значения в качестве показателя производительности, воспринимаемой пользователем.
Рассмотрим два SOC с запущенным тестом 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 секунды работы. Между тем, SOC 1 (более медленный SOC согласно Benchmark X) будет идеально гибким.
Использование отчетов об ошибках
Отчеты об ошибках иногда полезны для анализа производительности, но из-за того, что они очень тяжелые, они редко полезны для отладки спорадических проблем с джонками. Они могут дать некоторые подсказки о том, что система делала в данный момент времени, особенно если сбой был связан с переходом приложения (что регистрируется в отчете об ошибке). Отчеты об ошибках также могут указывать на более серьезные проблемы с системой, которые могут снизить ее эффективную емкость (например, тепловое регулирование или фрагментация памяти).
Использование сенсорной задержки
Несколько примеров плохого поведения исходят от TouchLatency, которая является предпочтительной периодической рабочей нагрузкой, используемой для Pixel и Pixel XL. Он доступен по адресу frameworks/base/tests/TouchLatency
и имеет два режима: задержка касания и прыгающий мяч (для переключения режимов нажмите кнопку в правом верхнем углу).
Тест на прыгающий мяч так же прост, как кажется: мяч постоянно прыгает по экрану, независимо от действий пользователя. Обычно это также самый сложный тест для идеального выполнения, но чем ближе он подходит к тесту без пропущенных кадров, тем лучше будет ваше устройство. Тест с прыгающим мячом сложен, потому что это тривиальная, но совершенно стабильная рабочая нагрузка, которая выполняется на очень низкой тактовой частоте (предполагается, что устройство имеет регулятор частоты; если вместо этого устройство работает с фиксированными тактовыми частотами, понизьте тактовую частоту ЦП/ГП почти до минимума). при первом запуске теста с прыгающим мячом). По мере того, как система приостанавливается и тактовые частоты приближаются к режиму ожидания, требуемое время ЦП/ГП на кадр увеличивается. Вы можете наблюдать за мячом и видеть, как что-то дергается, а также вы сможете увидеть пропущенные кадры в systrace.
Поскольку рабочая нагрузка настолько постоянна, вы можете определить большинство источников джиттера гораздо проще, чем в большинстве видимых пользователем рабочих нагрузок, отслеживая, что именно выполняется в системе во время каждого пропущенного кадра, а не через конвейер пользовательского интерфейса. Более низкие тактовые частоты усиливают эффекты джиттера, делая более вероятным, что любой джиттер вызывает пропущенный кадр. В результате, чем ближе TouchLatency к 60FPS, тем меньше вероятность того, что у вас будет плохое поведение системы, которое вызывает спорадические, трудно воспроизводимые рывки в больших приложениях.
Поскольку джиттер часто (но не всегда) не зависит от тактовой частоты, используйте тест, который выполняется на очень низких тактовых частотах, для диагностики джиттера по следующим причинам:
- Не весь джиттер не зависит от тактовой частоты; многие источники просто потребляют процессорное время.
- Регулятор должен приближать среднее время кадра к крайнему сроку, снижая часы, поэтому время, затраченное на выполнение работы, не связанной с пользовательским интерфейсом, может привести к пропуску кадра.