Evaluación del desempeño

Utilice Simpleperf para evaluar el rendimiento de un dispositivo. Simpleperf es una herramienta de creación de perfiles nativa tanto para aplicaciones como para procesos nativos en Android. Utilice CPU Profiler para inspeccionar el uso de CPU de la aplicación y la actividad de subprocesos en tiempo real.

Hay dos indicadores de rendimiento visibles para el usuario:

  • Rendimiento predecible y perceptible . ¿La interfaz de usuario (UI) elimina fotogramas o se procesa constantemente a 60 FPS? ¿El audio se reproduce sin artefactos ni estallidos? ¿Cuánto dura el retraso entre que el usuario toca la pantalla y el efecto se muestra en la pantalla?
  • Tiempo necesario para operaciones más largas (como abrir solicitudes).

El primero es más notorio que el segundo. Los usuarios normalmente notan el bloqueo, pero no podrán diferenciar el tiempo de inicio de la aplicación entre 500 ms y 600 ms a menos que estén mirando dos dispositivos uno al lado del otro. La latencia táctil se nota inmediatamente y contribuye significativamente a la percepción de un dispositivo.

Como resultado, en un dispositivo rápido, la canalización de la interfaz de usuario es lo más importante del sistema, además de lo necesario para mantenerla funcional. Esto significa que la canalización de la interfaz de usuario debe adelantarse a cualquier otro trabajo que no sea necesario para una interfaz de usuario fluida. Para mantener una interfaz de usuario fluida, la sincronización en segundo plano, la entrega de notificaciones y trabajos similares deben retrasarse si se puede ejecutar el trabajo de la interfaz de usuario. Es aceptable intercambiar el rendimiento de operaciones más largas (tiempo de ejecución de HDR+, inicio de aplicaciones, etc.) para mantener una interfaz de usuario fluida.

Capacidad frente a fluctuación

Al considerar el rendimiento del dispositivo, la capacidad y la fluctuación son dos métricas significativas.

Capacidad

La capacidad es la cantidad total de algún recurso que posee el dispositivo durante un período de tiempo. Pueden ser recursos de CPU, recursos de GPU, recursos de E/S, recursos de red, ancho de banda de memoria o cualquier métrica similar. Al examinar el rendimiento de todo el sistema, puede resultar útil abstraer los componentes individuales y asumir una única métrica que determine el rendimiento (especialmente cuando se ajusta un nuevo dispositivo porque las cargas de trabajo que se ejecutan en ese dispositivo probablemente sean fijas).

La capacidad de un sistema varía según los recursos informáticos en línea. Cambiar la frecuencia de la CPU/GPU es el medio principal para cambiar la capacidad, pero existen otros, como cambiar la cantidad de núcleos de la CPU en línea. En consecuencia, la capacidad de un sistema se corresponde con el consumo de energía; cambiar la capacidad siempre resulta en un cambio similar en el consumo de energía.

La capacidad requerida en un momento dado está determinada en gran medida por la aplicación en ejecución. Como resultado, la plataforma puede hacer poco para ajustar la capacidad requerida para una carga de trabajo determinada, y los medios para hacerlo se limitan a mejoras en el tiempo de ejecución (marco de Android, ART, Bionic, compilador/controladores de GPU, kernel).

Estar nervioso

Si bien la capacidad requerida para una carga de trabajo es fácil de ver, la fluctuación es un concepto más confuso. Para obtener una buena introducción a la fluctuación como impedimento para los sistemas rápidos, consulte EL CASO DEL RENDIMIENTO DE LA SUPERCOMPUTADORA FALTANTE: LOGRAR UN RENDIMIENTO ÓPTIMO EN LOS 8192 PROCESADORES DE ASCl Q. (Es una investigación de por qué la supercomputadora ASCI Q no logró el rendimiento esperado y es una excelente introducción a la optimización de sistemas grandes).

Esta página utiliza el término jitter para describir lo que el artículo ASCI Q llama ruido . Jitter es el comportamiento aleatorio del sistema que impide que se ejecute un trabajo perceptible. A menudo es un trabajo que debe ejecutarse, pero es posible que no tenga requisitos de tiempo estrictos que hagan que se ejecute en un momento determinado. Debido a que es aleatorio, es extremadamente difícil refutar la existencia de jitter para una carga de trabajo determinada. También es extremadamente difícil demostrar que una fuente conocida de fluctuación fue la causa de un problema de rendimiento en particular. Las herramientas más comúnmente utilizadas para diagnosticar las causas de la inquietud (como el rastreo o el registro) pueden introducir su propia inquietud.

Las fuentes de inquietud experimentadas en implementaciones de Android en el mundo real incluyen:

  • Retraso del programador
  • Manejadores de interrupciones
  • El código del controlador se ejecuta durante demasiado tiempo con la preferencia o las interrupciones deshabilitadas
  • Softirqs de larga duración
  • Contención de bloqueo (aplicación, marco, controlador del kernel, bloqueo de carpeta, bloqueo mmap)
  • Contención de descriptor de archivo donde un subproceso de baja prioridad mantiene el bloqueo en un archivo, impidiendo que se ejecute un subproceso de alta prioridad
  • Ejecutar código crítico para la interfaz de usuario en colas de trabajo donde podría retrasarse
  • Transiciones inactivas de CPU
  • Inicio sesión
  • Retrasos de E/S
  • Creación de procesos innecesarios (por ejemplo, transmisiones CONNECTIVITY_CHANGE)
  • Golpe de caché de página causado por memoria libre insuficiente

La cantidad de tiempo requerida para un período determinado de fluctuación puede disminuir o no a medida que aumenta la capacidad. Por ejemplo, si un controlador deja las interrupciones desactivadas mientras espera una lectura a través de un bus i2c, tomará una cantidad de tiempo fija independientemente de si la CPU está a 384 MHz o 2 GHz. Aumentar la capacidad no es una solución factible para mejorar el rendimiento cuando hay fluctuación. Como resultado, los procesadores más rápidos no suelen mejorar el rendimiento en situaciones de fluctuación limitada.

Finalmente, a diferencia de la capacidad, la fluctuación está casi exclusivamente dentro del dominio del proveedor del sistema.

Consumo de memoria

Tradicionalmente se culpa al consumo de memoria por el bajo rendimiento. Si bien el consumo en sí no es un problema de rendimiento, puede causar inestabilidad debido a una sobrecarga de baja memoria, reinicios de servicios y destrucción de caché de páginas. Reducir el consumo de memoria puede evitar las causas directas del bajo rendimiento, pero puede haber otras mejoras específicas que también eviten esas causas (por ejemplo, fijar el marco para evitar que se elimine cuando se paginará poco después).

Análisis del rendimiento inicial del dispositivo

Partir de un sistema funcional pero de bajo rendimiento e intentar corregir el comportamiento del sistema observando casos individuales de bajo rendimiento visibles para el usuario no es una buena estrategia. Debido a que el rendimiento deficiente generalmente no es fácilmente reproducible (es decir, fluctuaciones) o es un problema de la aplicación, demasiadas variables en todo el sistema impiden que esta estrategia sea efectiva. Como resultado, es muy fácil identificar erróneamente las causas y realizar mejoras menores mientras se pierden oportunidades sistémicas para corregir el rendimiento en todo el sistema.

En su lugar, utilice el siguiente enfoque general cuando abra un nuevo dispositivo:

  1. Haga que el sistema se inicie en la interfaz de usuario con todos los controladores ejecutándose y algunas configuraciones básicas del regulador de frecuencia (si cambia la configuración del regulador de frecuencia, repita todos los pasos a continuación).
  2. Asegúrese de que el kernel admita el punto de seguimiento sched_blocked_reason , así como otros puntos de seguimiento en el canal de visualización que indican cuándo se entrega el fotograma a la pantalla.
  3. Realice largos seguimientos de toda la canalización de la interfaz de usuario (desde la recepción de información a través de una IRQ hasta el escaneo final) mientras ejecuta una carga de trabajo liviana y consistente (por ejemplo, UiBench o la prueba de bola en TouchLatency) .
  4. Corrija las caídas de cuadros detectadas en la carga de trabajo liviana y consistente.
  5. Repita los pasos 3 y 4 hasta que pueda ejecutar sin fotogramas perdidos durante más de 20 segundos a la vez.
  6. Continúe con otras fuentes de basura visibles para el usuario.

Otras cosas sencillas que puedes hacer desde el principio al abrir el dispositivo incluyen:

  • Asegúrese de que su kernel tenga el parche de punto de seguimiento sched_blocked_reason . Este punto de seguimiento está habilitado con la categoría de seguimiento programada en systrace y proporciona la función responsable de dormir cuando ese subproceso entra en suspensión ininterrumpida. Es fundamental para el análisis del rendimiento porque el sueño ininterrumpido es un indicador muy común de inquietud.
  • Asegúrese de tener suficiente seguimiento para la GPU y las canalizaciones de visualización. En los SOC de Qualcomm recientes, los puntos de seguimiento se habilitan mediante:
  • adb shell "echo 1 > /d/tracing/events/kgsl/enable"
    adb shell "echo 1 > /d/tracing/events/mdss/enable"
    

    Estos eventos permanecen habilitados cuando ejecuta systrace para que pueda ver información adicional en el seguimiento sobre la canalización de visualización (MDSS) en la sección mdss_fb0 . En los SOC de Qualcomm, no verá ninguna información adicional sobre la GPU en la vista estándar de systrace, pero los resultados están presentes en el seguimiento mismo (para obtener más detalles, consulte Comprensión de systrace ).

    Lo que se desea de este tipo de seguimiento de visualización es un evento único que indique directamente que se ha entregado un fotograma a la pantalla. A partir de ahí, puedes determinar si has alcanzado el tiempo de fotograma correctamente; Si el evento X n ocurre menos de 16,7 ms después del evento X n-1 (suponiendo una pantalla de 60 Hz), entonces sabrá que no se bloqueó. Si su SOC no proporciona dichas señales, trabaje con su proveedor para obtenerlas. Depurar la fluctuación es extremadamente difícil sin una señal definitiva de finalización de la trama.

Usando puntos de referencia sintéticos

Los puntos de referencia sintéticos son útiles para garantizar que la funcionalidad básica de un dispositivo esté presente. Sin embargo, no es útil tratar los puntos de referencia como un indicador del rendimiento percibido del dispositivo.

Según las experiencias con los SOC, las diferencias en el rendimiento de las pruebas comparativas sintéticas entre los SOC no se correlacionan con una diferencia similar en el rendimiento perceptible de la interfaz de usuario (número de fotogramas eliminados, tiempo de fotograma del percentil 99, etc.). Los puntos de referencia sintéticos son puntos de referencia únicamente de capacidad; La fluctuación afecta el rendimiento medido de estos puntos de referencia solo al robar tiempo de la operación masiva del punto de referencia. Como resultado, las puntuaciones de referencia sintéticas son en su mayoría irrelevantes como métrica del desempeño percibido por el usuario.

Considere dos SOC que ejecutan Benchmark X y representan 1000 cuadros de interfaz de usuario e informan el tiempo total de renderizado (una puntuación más baja es mejor).

  • SOC 1 procesa cada cuadro de Benchmark X en 10 ms y obtiene una puntuación de 10 000.
  • SOC 2 procesa el 99 % de los fotogramas en 1 ms, pero el 1 % de los fotogramas en 100 ms y obtiene una puntuación de 19 900, una puntuación dramáticamente mejor.

Si el punto de referencia es indicativo del rendimiento real de la interfaz de usuario, SOC 2 sería inutilizable. Suponiendo una frecuencia de actualización de 60 Hz, SOC 2 tendría un cuadro irregular cada 1,5 segundos de funcionamiento. Mientras tanto, el SOC 1 (el SOC más lento según el Benchmark X) sería perfectamente fluido.

Usar informes de errores

Los informes de errores a veces son útiles para el análisis de rendimiento, pero debido a que son tan pesados, rara vez son útiles para depurar problemas esporádicos. Pueden proporcionar algunas pistas sobre lo que estaba haciendo el sistema en un momento dado, especialmente si el bloqueo se produjo en torno a una transición de la aplicación (que se registra en un informe de error). Los informes de errores también pueden indicar cuándo hay algún problema más general con el sistema que podría reducir su capacidad efectiva (como la limitación térmica o la fragmentación de la memoria).

Usando TouchLatency

Varios ejemplos de mal comportamiento provienen de TouchLatency, que es la carga de trabajo periódica preferida utilizada para Pixel y Pixel XL. Está disponible en frameworks/base/tests/TouchLatency y tiene dos modos: latencia táctil y pelota que rebota (para cambiar de modo, haga clic en el botón en la esquina superior derecha).

La prueba de la pelota que rebota es exactamente tan simple como parece: una pelota rebota por la pantalla para siempre, independientemente de la entrada del usuario. Por lo general, también es, con diferencia , la prueba más difícil de ejecutar a la perfección, pero cuanto más cerca esté de ejecutarse sin pérdida de fotogramas, mejor será su dispositivo. La prueba de la pelota que rebota es difícil porque es una carga de trabajo trivial pero perfectamente consistente que se ejecuta a un reloj muy bajo (esto supone que el dispositivo tiene un regulador de frecuencia; si, en cambio, el dispositivo funciona con relojes fijos, reduzca la velocidad de la CPU/GPU hasta casi el mínimo). al ejecutar la prueba de la pelota que rebota por primera vez). A medida que el sistema se detiene y los relojes se acercan al estado de inactividad, aumenta el tiempo requerido de CPU/GPU por cuadro. Puedes observar la pelota y ver cosas que fallan, y también podrás ver los fotogramas perdidos en systrace.

Debido a que la carga de trabajo es tan consistente, puede identificar la mayoría de las fuentes de fluctuación mucho más fácilmente que en la mayoría de las cargas de trabajo visibles para el usuario al realizar un seguimiento de qué se ejecuta exactamente en el sistema durante cada fotograma perdido en lugar del proceso de interfaz de usuario. Los relojes más bajos amplifican los efectos de la fluctuación al hacer que sea más probable que cualquier fluctuación provoque una pérdida de fotograma. Como resultado, cuanto más cerca esté TouchLatency de 60 FPS, es menos probable que tenga malos comportamientos en el sistema que causen bloqueos esporádicos y difíciles de reproducir en aplicaciones más grandes.

Como la fluctuación a menudo (pero no siempre) no varía con la velocidad del reloj, utilice una prueba que se ejecute a velocidades de reloj muy bajas para diagnosticar la fluctuación por las siguientes razones:

  • No todo el jitter es invariante en la velocidad del reloj; Muchas fuentes simplemente consumen tiempo de CPU.
  • El gobernador debe acercar el tiempo promedio del fotograma a la fecha límite reduciendo el tiempo, de modo que el tiempo dedicado a ejecutar trabajos que no sean de interfaz de usuario puede llevarlo al límite y perder un fotograma.