Novedades de productos

Mejorar el rendimiento de Android: presentamos AutoFDO para el kernel

Lectura de 4 minutos
Yabin Cui
Ingeniero de software

Somos el equipo de la cadena de herramientas LLVM de Android. Una de nuestras principales prioridades es mejorar el rendimiento de Android mediante técnicas de optimización en el ecosistema LLVM. Buscamos constantemente formas de hacer que Android sea más rápido, fluido y eficiente. Aunque gran parte de nuestro trabajo de optimización se lleva a cabo en el espacio de usuario, el kernel sigue siendo el núcleo del sistema. Hoy nos complace compartir cómo estamos incorporando la optimización automática dirigida por comentarios (AutoFDO) al kernel de Android para ofrecer a los usuarios mejoras significativas en el rendimiento.

¿Qué es AutoFDO?

Durante una compilación de software estándar, el compilador toma miles de pequeñas decisiones, como si debe insertar una función y qué rama de una condicional es probable que se tome, en función de las sugerencias de código estático.Aunque estas heurísticas son útiles, no siempre predicen con precisión la ejecución del código durante el uso del teléfono en el mundo real.

AutoFDO cambia esto usando patrones de ejecución del mundo real para guiar al compilador. Estos patrones representan las rutas de ejecución de instrucciones más habituales que sigue el código durante el uso real, que se capturan registrando el historial de ramificaciones de la CPU. Aunque estos datos se pueden recoger de los dispositivos de la flota, en el caso del kernel, los sintetizamos en un entorno de laboratorio mediante cargas de trabajo representativas, como ejecutar las 100 aplicaciones más populares. Usamos un perfilador de muestreo para recoger estos datos, que identifica qué partes del código están "activas" (se usan con frecuencia) y cuáles están "inactivas". Cuando recompilamos el kernel con estos perfiles, el compilador puede tomar decisiones de optimización mucho más inteligentes y adaptadas a las cargas de trabajo reales de Android.

Para entender el impacto de esta optimización, ten en cuenta estos datos clave:

  • En Android, el kernel representa aproximadamente el 40% del tiempo de CPU.
  • Ya estamos usando AutoFDO para optimizar los ejecutables y las bibliotecas nativas en el espacio de usuario, lo que nos ha permitido mejorar el inicio de aplicaciones en frío en un 4% y reducir el tiempo de arranque en un 1 %.

Mejoras de rendimiento en el mundo real

Hemos observado mejoras impresionantes en las métricas clave de Android gracias al uso de perfiles de entornos de laboratorio controlados. Estos perfiles se han recogido mediante el rastreo y el lanzamiento de aplicaciones, y se han medido en dispositivos Pixel con los kernels 6.1, 6.6 y 6.12.

A continuación, se indican las mejoras más notables. Puedes consultar los detalles de los perfiles de AutoFDO de estas versiones del kernel en los repositorios del kernel de Android correspondientes a los kernels android16-6.12 y android15-6.6.

boosting_2.png

No se trata solo de cifras teóricas. Esto se traduce en una interfaz más ágil, un cambio de aplicaciones más rápido, una mayor duración de la batería y un dispositivo más eficiente en general para el usuario final.

Cómo funciona: la canalización

Nuestra estrategia de implementación incluye una sofisticada canalización para asegurarnos de que los perfiles sigan siendo relevantes y de que el rendimiento se mantenga estable.

boosting_3.png

Paso 1: Recogida de perfiles

Aunque usamos nuestra flota de pruebas interna para crear perfiles de los archivos binarios del espacio de usuario, hemos cambiado a un entorno de laboratorio controlado para la imagen genérica del kernel (GKI). Al desacoplar la creación de perfiles del ciclo de lanzamiento del dispositivo, se pueden realizar actualizaciones flexibles e inmediatas independientemente de las versiones del kernel implementadas. Lo más importante es que las pruebas confirman que estos datos de laboratorio ofrecen mejoras de rendimiento comparables a las de las flotas reales.

  • Herramientas y entorno: flasheamos dispositivos de prueba con la imagen del kernel más reciente y usamos simpleperf para capturar flujos de ejecución de instrucciones. Este proceso se basa en las funciones de hardware para registrar el historial de ramificación, en concreto, mediante  ARM Embedded Trace Extension (ETE) y ARM Trace Buffer Extension (TRBE) en dispositivos Pixel.
  • Cargas de trabajo:  creamos una carga de trabajo representativa con las 100 aplicaciones más populares de la Suite de Pruebas de Compatibilidad de Aplicaciones Android (C-Suite). Para recoger los datos más precisos, nos centramos en lo siguiente:
    • Inicio de aplicaciones: optimizar los retrasos más visibles para los usuarios
    • Rastreo de aplicaciones basado en IA: simula interacciones de usuario contiguas y en evolución.
    • Monitorización en todo el sistema: captura no solo las actividades de las aplicaciones en primer plano, sino también las cargas de trabajo críticas en segundo plano y las comunicaciones entre procesos.
  • Validación: esta carga de trabajo sintetizada muestra una similitud del 85% con los patrones de ejecución recogidos de nuestra flota interna.
  • Datos segmentados: al repetir estas pruebas las veces suficientes, capturamos patrones de ejecución de alta fidelidad que representan con precisión la interacción del usuario en el mundo real con las aplicaciones más populares. Además, este marco extensible nos permite integrar sin problemas cargas de trabajo y comparativas adicionales para ampliar nuestra cobertura.

Paso 2: Procesamiento del perfil

Post-procesamos los datos de traza sin procesar para asegurarnos de que estén limpios, sean eficaces y estén listos para el compilador.

  • Agregación: consolidamos los datos de varias ejecuciones de pruebas y dispositivos en una sola vista del sistema.
  • Conversión:  convertimos las trazas sin procesar al formato de perfil de AutoFDO y filtramos los símbolos no deseados según sea necesario.
  • Recorte de perfiles: recortamos los perfiles para eliminar los datos de las funciones "frías", lo que les permite usar la optimización estándar. De esta forma, se evitan regresiones en el código que se usa poco y aumentos innecesarios en el tamaño binario.

Paso 3: Prueba de perfil

Antes de implementarse, los perfiles se someten a una verificación rigurosa para garantizar que ofrezcan un rendimiento constante sin riesgos de estabilidad.

  • Análisis de perfil y binario: comparamos estrictamente el contenido del nuevo perfil (incluidas las funciones activas, el número de muestras y el tamaño del perfil) con las versiones anteriores. También usamos el perfil para crear una nueva imagen del kernel y analizamos los archivos binarios para asegurarnos de que los cambios en la sección de texto se ajustan a lo esperado.
  • Verificación del rendimiento: ejecutamos comparativas específicas en la nueva imagen del kernel. De esta forma, se confirma que mantiene las mejoras de rendimiento establecidas por las bases anteriores.

Actualizaciones continuas

El código "se desvía" de forma natural con el tiempo, por lo que un perfil estático acabaría perdiendo su eficacia. Para mantener el máximo rendimiento, ejecutamos la canalización de forma continua para ofrecer actualizaciones periódicas:

  • Actualización periódica: actualizamos los perfiles en las ramas LTS del kernel de Android antes de cada lanzamiento de GKI para asegurarnos de que cada compilación incluya los datos de perfil más recientes.
  • Ampliación futura: actualmente, estamos ofreciendo estas actualizaciones a las ramas android16-6.12 y android15-6.6, y ampliaremos la compatibilidad a versiones más recientes de GKI, como la próxima android17-6.18.

Garantizar la estabilidad

Una pregunta habitual sobre la optimización guiada por perfil es si conlleva riesgos de estabilidad. Como AutoFDO influye principalmente en la heurística del compilador, como la inserción de funciones y el diseño del código, en lugar de alterar la lógica del código fuente, conserva la integridad funcional del kernel. Esta tecnología ya se ha probado a gran escala y lleva años siendo una optimización estándar para las bibliotecas de la plataforma Android, ChromeOS y la infraestructura de servidores de Google.

Para garantizar aún más un comportamiento coherente, aplicamos una estrategia "conservadora por defecto". Las funciones que no se recogen en nuestros perfiles de alta fidelidad se optimizan mediante métodos de compilación estándar. De esta forma, se asegura de que las partes "frías" o que se ejecutan con poca frecuencia del kernel se comporten exactamente igual que en una compilación estándar, lo que evita regresiones de rendimiento o comportamientos inesperados en casos extremos.

Planes de futuro

Actualmente, estamos implementando AutoFDO en las ramas android16-6.12 y android15-6.6. Además de este lanzamiento inicial, vemos varias vías prometedoras para mejorar aún más la tecnología:

  • Mayor cobertura: tenemos previsto implementar perfiles de AutoFDO en versiones más recientes del kernel de GKI y en otros destinos de compilación, además de la compatibilidad actual con aarch64.
  • Optimización de módulos de GKI: actualmente, nuestra optimización se centra en el archivo binario principal del kernel (vmlinux). Ampliar AutoFDO a los módulos de GKI podría mejorar el rendimiento de una parte mayor del subsistema del kernel.
  • Compatibilidad con módulos de proveedores: también nos interesa ofrecer compatibilidad con AutoFDO para módulos de proveedores creados con el Driver Development Kit (DDK). Como ya se ofrece asistencia en nuestro sistema de compilación (Kleaf) y en nuestras herramientas de creación de perfiles (simpleperf), los proveedores pueden aplicar estas mismas técnicas de optimización a sus controladores de hardware específicos.
  • Cobertura de perfiles más amplia: se pueden recoger perfiles de una gama más amplia de recorridos de usuario críticos (CUJs) para optimizarlos.

Al incorporar AutoFDO al kernel de Android, nos aseguramos de que la base del SO esté optimizada para la forma en que usas tu dispositivo cada día.

Escrito por:

Seguir leyendo