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. Use CPU Profiler para inspeccionar el uso de la 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) deja caer fotogramas o se renderiza constantemente a 60 FPS? ¿El audio se reproduce sin artefactos ni chasquidos? ¿Cuánto tiempo transcurre entre que el usuario toca la pantalla y el efecto que se muestra en la pantalla?
- Periodo de tiempo requerido para operaciones más largas (como abrir aplicaciones).
El primero se nota más que el segundo. Los usuarios suelen notar bloqueos, pero no podrán diferenciar entre 500 ms y 600 ms de tiempo de inicio de la aplicación a menos que estén mirando dos dispositivos uno al lado del otro. La latencia táctil se nota de inmediato 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 en el sistema además de lo necesario para mantener la canalización de la interfaz de usuario 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 vs fluctuación
Al considerar el rendimiento del dispositivo, la capacidad y la inestabilidad son dos métricas significativas.
Capacidad
La capacidad es la cantidad total de algún recurso que posee el dispositivo durante un cierto período de tiempo. Estos 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 ser útil abstraer los componentes individuales y asumir una sola métrica que determina 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 CPU/GPU es el medio principal para cambiar la capacidad, pero existen otros, como cambiar la cantidad de núcleos de 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 de manera abrumadora 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
Mientras que la capacidad requerida para una carga de trabajo es fácil de ver, la inestabilidad es un concepto más nebuloso. Para una buena introducción a la fluctuación de fase como impedimento para los sistemas rápidos, consulte EL CASO DE LA FALTA DE RENDIMIENTO DE LA SUPERCOMPUTADORA: LOGRAR EL 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 grandes sistemas).
Esta página usa el término jitter para describir lo que el documento ASCI Q llama ruido . Jitter es el comportamiento aleatorio del sistema que evita 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 probar que una fuente conocida de fluctuación fue la causa de un problema de rendimiento en particular. Las herramientas más utilizadas para diagnosticar las causas de la fluctuación (como el seguimiento o el registro) pueden introducir su propia fluctuación.
Las fuentes de inestabilidad experimentadas en implementaciones de Android en el mundo real incluyen:
- Retraso del programador
- Controladores de interrupciones
- El código del controlador se ejecuta durante demasiado tiempo con preferencia o interrupciones deshabilitadas
- Softirqs de ejecución prolongada
- Contención de bloqueo (aplicación, marco, controlador de kernel, bloqueo de carpeta, bloqueo mmap)
- Contención del descriptor de archivo donde un subproceso de baja prioridad mantiene el bloqueo en un archivo, lo que impide que se ejecute un subproceso de alta prioridad
- Ejecución de 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 (p. ej., transmisiones CONNECTIVITY_CHANGE)
- Golpe de memoria caché de página causado por memoria libre insuficiente
La cantidad de tiempo requerida para un período dado de fluctuación puede disminuir o no a medida que aumenta la capacidad. Por ejemplo, si un controlador deja las interrupciones deshabilitadas mientras espera una lectura de un bus i2c, tomará una cantidad de tiempo fija, independientemente de si la CPU está a 384 MHz o 2 GHz. El aumento de la capacidad no es una solución factible para mejorar el rendimiento cuando se trata de fluctuaciones. Como resultado, los procesadores más rápidos normalmente no mejorarán el rendimiento en situaciones de fluctuación limitada.
Finalmente, a diferencia de la capacidad, el jitter está casi completamente 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 fluctuaciones debido a la sobrecarga de lowmemorykiller, los reinicios del servicio y la paliza de la memoria caché de la página. La reducción del consumo de memoria puede evitar las causas directas del rendimiento deficiente, pero puede haber otras mejoras específicas que también evitan esas causas (por ejemplo, fijar el marco para evitar que se pagine cuando se pagine poco después).
Análisis del rendimiento inicial del dispositivo
Comenzar con un sistema funcional pero de bajo rendimiento e intentar corregir el comportamiento del sistema observando casos individuales de bajo rendimiento visible para el usuario no es una buena estrategia. Debido a que el rendimiento deficiente generalmente no es fácilmente reproducible (es decir, fluctuación) o es un problema de la aplicación, demasiadas variables en el sistema completo 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 al abrir un nuevo dispositivo:
- Haga que el sistema se inicie en la interfaz de usuario con todos los controladores en ejecución 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).
- Asegúrese de que el kernel admita el punto de
sched_blocked_reason
, así como otros puntos de seguimiento en la canalización de visualización que indican cuándo se envía el marco a la pantalla. - Realice seguimientos largos de toda la canalización de la interfaz de usuario (desde la recepción de la entrada a través de una IRQ hasta el escaneo final) mientras ejecuta una carga de trabajo liviana y consistente (p. ej., UiBench o la prueba de bola en TouchLatency) .
- Solucione las caídas de fotogramas detectadas en la carga de trabajo ligera y constante.
- Repita los pasos 3 y 4 hasta que pueda ejecutar sin pérdida de fotogramas durante más de 20 segundos a la vez.
- Pase a otras fuentes de bloqueo visibles para el usuario.
Otras cosas simples que puede hacer desde el principio en la activación del dispositivo incluyen:
- Asegúrese de que su núcleo tenga el parche de punto de seguimiento sched_blocked_reason . Este punto de rastreo está habilitado con la categoría de rastreo 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 de rendimiento porque el sueño ininterrumpido es un indicador muy común de inestabilidad.
- Asegúrese de tener suficiente seguimiento para la GPU y las canalizaciones de visualización. En los SOC Qualcomm recientes, los puntos de rastreo 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 propio seguimiento (para obtener detalles, consulte Comprensión de systrace ).
Lo que desea de este tipo de seguimiento de pantalla es un solo evento que indique directamente que se ha enviado un cuadro a la pantalla. A partir de ahí, puede determinar si ha alcanzado el tiempo de marco con éxito; 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 produjo un bloqueo. Si su SOC no proporciona tales señales, trabaje con su proveedor para obtenerlas. La depuración de fluctuaciones es extremadamente difícil sin una señal definitiva de finalización de trama.
Uso de 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, tratar los puntos de referencia como un indicador del rendimiento percibido del dispositivo no es útil.
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 perdidos, tiempo de fotogramas del percentil 99, etc.). Los puntos de referencia sintéticos son puntos de referencia solo 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 comparativas sintéticas son en su mayoría irrelevantes como métrica del rendimiento percibido por el usuario.
Considere dos SOC que ejecuten Benchmark X que represente 1000 cuadros de interfaz de usuario e informe el tiempo de procesamiento total (la puntuación más baja es mejor).
- SOC 1 procesa cada fotograma 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 considerablemente 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 s de funcionamiento. Mientras tanto, SOC 1 (el SOC más lento según Benchmark X) sería perfectamente fluido.
Uso de 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 de bloqueo esporádicos. Pueden proporcionar algunas pistas sobre lo que estaba haciendo el sistema en un momento determinado, 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 amplio con el sistema que podría reducir su capacidad efectiva (como la limitación térmica o la fragmentación de la memoria).
Uso de 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 tan simple como parece: una pelota rebota alrededor de la pantalla para siempre, independientemente de la entrada del usuario. Por lo general, también es, con mucho, la prueba más difícil de ejecutar a la perfección, pero cuanto más se acerque a ejecutarse sin perder 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 el dispositivo funciona con relojes fijos, reduzca la frecuencia de la CPU/GPU casi al mínimo). cuando se ejecuta la prueba de la pelota que rebota por primera vez). A medida que el sistema se desactiva y los relojes se acercan a la inactividad, aumenta el tiempo de CPU/GPU requerido por cuadro. Puede mirar la pelota y ver cómo se mueven las cosas, y también podrá 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 rastrear qué se está ejecutando exactamente en el sistema durante cada marco perdido en lugar de la canalización de la interfaz de usuario. Los relojes más bajos amplifican los efectos del jitter al hacer que sea más probable que cualquier jitter provoque una caída de fotogramas. Como resultado, cuanto más se acerque TouchLatency a 60FPS, es menos probable que tenga malos comportamientos del sistema que provoquen bloqueos esporádicos y difíciles de reproducir en aplicaciones más grandes.
Dado que la fluctuación de fase es a menudo (pero no siempre) invariable con la velocidad del reloj, utilice una prueba que se ejecute a velocidades de reloj muy bajas para diagnosticar la fluctuación de fase por los siguientes motivos:
- No todo el jitter es invariable con la velocidad del reloj; muchas fuentes solo consumen tiempo de CPU.
- El gobernador debe hacer que el tiempo de cuadro promedio se acerque a la fecha límite reduciendo el reloj, de modo que el tiempo dedicado a ejecutar el trabajo que no es de interfaz de usuario puede llevarlo al límite y dejar caer un cuadro.