Actualités des produits

Améliorer les performances d'Android : présentation d'AutoFDO pour le noyau

Temps de lecture : 4 min
Yabin Cui
Ingénieur logiciel

Nous sommes l'équipe de la chaîne d'outils Android LLVM. L'une de nos principales priorités est d'améliorer les performances d'Android grâce à des techniques d'optimisation dans l'écosystème LLVM. Nous cherchons constamment à rendre Android plus rapide, plus fluide et plus efficace. Bien que la majeure partie de notre travail d'optimisation se déroule dans l'espace utilisateur, le noyau reste le cœur du système. Aujourd'hui, nous sommes heureux de vous annoncer que nous intégrons l'optimisation automatique basée sur le feedback (AutoFDO) au noyau Android pour offrir aux utilisateurs des gains de performances significatifs.

Qu'est-ce qu'AutoFDO ?

Lors d'une compilation logicielle standard, le compilateur prend des milliers de petites décisions, par exemple s'il faut insérer une fonction et quelle branche d'une conditionnelle est susceptible d'être prise, en fonction d'indices de code statiques.Bien que ces heuristiques soient utiles, elles ne prédisent pas toujours avec précision l'exécution du code lors de l'utilisation réelle du téléphone.

AutoFDO change cela en utilisant des modèles d'exécution réels pour guider le compilateur. Ces modèles représentent les chemins d'exécution d'instructions les plus courants empruntés par le code lors de l'utilisation réelle, capturés en enregistrant l'historique des branchements du processeur. Bien que ces données puissent être collectées à partir d'appareils de flotte, nous les synthétisons pour le noyau dans un environnement de laboratoire à l'aide de charges de travail représentatives, comme l'exécution des 100 applications les plus populaires. Nous utilisons un profileur d'échantillonnage pour capturer ces données, en identifiant les parties du code qui sont "chaudes" (fréquemment utilisées) et celles qui sont "froides". Lorsque nous reconstruisons le noyau avec ces profils, le compilateur peut prendre des décisions d'optimisation beaucoup plus intelligentes, adaptées aux charges de travail Android réelles.

Pour comprendre l'impact de cette optimisation, tenez compte des faits clés suivants :

  • Sur Android, le noyau représente environ 40 % du temps CPU.
  • Nous utilisons déjà AutoFDO pour optimiser les exécutables et les bibliothèques natifs dans l'espace utilisateur, ce qui permet d'améliorer le lancement à froid des applications d'environ 4 % et de réduire le temps de démarrage de 1 %.

Des performances concrètes

Nous avons constaté des améliorations impressionnantes au niveau des métriques Android clés en utilisant des profils issus d'environnements de test contrôlés. Ces profils ont été collectés à l'aide de l'exploration et du lancement d'applications, et mesurés sur des appareils Pixel avec les noyaux 6.1, 6.6 et 6.12.

Les améliorations les plus notables sont listées ci-dessous. Pour en savoir plus sur les profils AutoFDO de ces versions du noyau, consultez les dépôts de noyau Android respectifs pour les noyaux android16-6.12 et android15-6.6.

boosting_2.png

Il ne s'agit pas de simples chiffres théoriques. Cela se traduit par une interface plus réactive, un changement d'application plus rapide, une autonomie de la batterie prolongée et un appareil globalement plus réactif pour l'utilisateur final.

Fonctionnement : le pipeline

Notre stratégie de déploiement implique un pipeline sophistiqué pour garantir la pertinence des profils et la stabilité des performances.

boosting_3.png

Étape 1 : Collecte des profils

Bien que nous nous appuyions sur notre parc de tests internes pour profiler les binaires de l'espace utilisateur, nous sommes passés à un environnement de laboratoire contrôlé pour l'image générique du noyau (GKI). En dissociant le profilage du cycle de publication des appareils, il est possible d'effectuer des mises à jour flexibles et immédiates, indépendamment des versions du noyau déployées. Les tests confirment que ces données en laboratoire permettent d'améliorer les performances de manière comparable à celles des flottes réelles.

  • Outils et environnement : nous flashons les appareils de test avec la dernière image du noyau et utilisons simpleperf pour capturer les flux d'exécution des instructions. Ce processus repose sur les capacités matérielles permettant d'enregistrer l'historique des branches, en utilisant plus précisément les extensions  ARM Embedded Trace Extension (ETE) et ARM Trace Buffer Extension (TRBE) sur les appareils Pixel.
  • Charges de travail : nous construisons une charge de travail représentative à l'aide des 100 applications les plus populaires de la suite de tests de compatibilité des applications Android (C-Suite). Pour capturer les données les plus précises possible, nous nous concentrons sur les éléments suivants :
    • Lancement d'applications : optimiser les délais les plus visibles pour les utilisateurs
    • Exploration des applications basée sur l'IA : simuler des interactions utilisateur continues et évolutives
    • Surveillance à l'échelle du système : capture non seulement les activités des applications au premier plan, mais aussi les charges de travail critiques en arrière-plan et les communications entre les processus.
  • Validation : cette charge de travail synthétisée présente une similitude de 85 % avec les modèles d'exécution collectés à partir de notre parc interne.
  • Données ciblées : en répétant ces tests suffisamment de fois, nous capturons des schémas d'exécution de haute fidélité qui représentent précisément l'interaction des utilisateurs réels avec les applications les plus populaires. De plus, ce framework extensible nous permet d'intégrer facilement des charges de travail et des benchmarks supplémentaires pour élargir notre couverture.

Étape 2 : Traitement du profil

Nous post-traitons les données brutes de trace pour nous assurer qu'elles sont propres, efficaces et prêtes pour le compilateur.

  • Agrégation : nous consolidons les données de plusieurs exécutions de tests et appareils dans une seule vue système.
  • Conversion  : nous convertissons les traces brutes au format de profil AutoFDO, en filtrant les symboles indésirables si nécessaire.
  • Élagage des profils : nous élaguons les profils pour supprimer les données des fonctions "froides", ce qui leur permet d'utiliser l'optimisation standard. Cela permet d'éviter les régressions dans le code rarement utilisé et d'éviter d'augmenter inutilement la taille du binaire.

Étape 3 : Tester le profil

Avant le déploiement, les profils sont soumis à une vérification rigoureuse pour s'assurer qu'ils offrent des performances cohérentes sans risque de stabilité.

  • Analyse du profil et du fichier binaire : nous comparons rigoureusement le contenu du nouveau profil (y compris les fonctions actives, le nombre d'échantillons et la taille du profil) aux versions précédentes. Nous utilisons également le profil pour créer une image de noyau, en analysant les binaires pour nous assurer que les modifications apportées à la section de texte sont conformes aux attentes.
  • Vérification des performances : nous exécutons des benchmarks ciblés sur la nouvelle image du noyau. Cela confirme qu'il maintient les améliorations de performances établies par les références précédentes.

Mises à jour continues

Le code "dérive" naturellement au fil du temps. Un profil statique finirait donc par perdre son efficacité. Pour maintenir des performances optimales, nous exécutons le pipeline en continu afin de générer des mises à jour régulières :

  • Actualisation régulière : nous actualisons les profils dans les branches LTS du noyau Android avant chaque version GKI, ce qui garantit que chaque build inclut les données de profil les plus récentes.
  • Expansion future : nous déployons actuellement ces mises à jour sur les branches android16-6.12 et android15-6.6, et nous étendrons la compatibilité aux versions GKI plus récentes, comme la prochaine version android17-6.18.

Assurer la stabilité

Une question fréquente concernant l'optimisation guidée par le profil est de savoir si elle présente des risques de stabilité. Étant donné qu'AutoFDO influence principalement les heuristiques du compilateur, telles que l'intégration de fonctions et la mise en page du code, plutôt que de modifier la logique du code source, il préserve l'intégrité fonctionnelle du noyau. Cette technologie a déjà fait ses preuves à grande échelle. Elle sert d'optimisation standard pour les bibliothèques de la plate-forme Android, ChromeOS et l'infrastructure de serveur de Google depuis des années.

Pour garantir un comportement cohérent, nous appliquons une stratégie "conservatrice par défaut". Les fonctions non capturées dans nos profils haute fidélité sont optimisées à l'aide de méthodes de compilation standards. Cela permet de s'assurer que les parties "froides" ou rarement exécutées du noyau se comportent exactement comme dans une version standard, ce qui évite les régressions de performances ou les comportements inattendus dans les cas extrêmes.

Perspectives d'avenir

Nous déployons actuellement AutoFDO dans les branches android16-6.12 et android15-6.6. Au-delà de ce déploiement initial, nous envisageons plusieurs pistes prometteuses pour améliorer encore cette technologie :

  • Couverture étendue : nous prévoyons de déployer des profils AutoFDO sur des versions plus récentes du noyau GKI et sur d'autres cibles de compilation au-delà de la prise en charge actuelle de aarch64.
  • Optimisation des modules GKI : actuellement, notre optimisation est axée sur le binaire du noyau principal (vmlinux). L'extension d'AutoFDO aux modules GKI pourrait améliorer les performances d'une plus grande partie du sous-système du noyau.
  • Prise en charge des modules fournisseur : nous souhaitons également prendre en charge AutoFDO pour les modules fournisseur créés à l'aide du Driver Development Kit (DDK). Grâce à la prise en charge déjà disponible dans notre système de compilation (Kleaf) et nos outils de profilage (simpleperf), les fournisseurs peuvent appliquer ces mêmes techniques d'optimisation à leurs pilotes matériels spécifiques.
  • Couverture plus large des profils : vous pouvez collecter des profils à partir d'un plus grand nombre de critical user journeys (CUJ) pour les optimiser.

En intégrant AutoFDO au noyau Android, nous nous assurons que la base même de l'OS est optimisée pour la façon dont vous utilisez votre appareil au quotidien.

Écrit par :

Lire la suite