Actualités sur les produits

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

Temps de lecture : 4 min
Afficher le profil de Charles Munger
Yabin Cui Ingénieur logiciel

Nous sommes l'équipe de la chaîne d'outils LLVM Android. 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 qu'une grande 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 ravis de vous expliquer comment nous intégrons l'optimisation automatique guidée par les commentaires (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 intégrer une fonction et quelle branche d'une condition 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 la flotte, nous les synthétisons pour le kernel 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 recompilons 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 kernel 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 d'environ 4% le démarrage à froid des applications et de réduire de 1% le temps de démarrage.

Améliorations des performances en conditions réelles

Nous avons constaté des améliorations impressionnantes des métriques Android clés en exploitant les profils d'environnements de laboratoire 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. Vous trouverez des informations sur les profils AutoFDO pour ces versions de noyau dans les dépôts de noyau Android respectifs pour les noyaux android16-6.12 et android15-6.6.

boosting_2.png

Ces chiffres ne sont pas que théoriques. Ils se traduisent par une interface plus réactive, un changement d'application plus rapide, une autonomie 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 que les profils restent pertinents et que les performances restent stables.

boosting_3.png

Étape 1 : Collecte de profils

Bien que nous nous appuyions sur notre parc de tests interne pour profiler les binaires de l'espace utilisateur, nous sommes passés à un environnement de laboratoire contrôlé pour l'image de noyau générique (GKI). En dissociant le profilage du cycle de publication de l'appareil, vous pouvez effectuer des mises à jour flexibles et immédiates, indépendamment des versions de noyau déployées. Les tests confirment que ces données de laboratoire permettent d'obtenir des gains de performances comparables à ceux des parcs réels.

  • Outils et environnement : nous flashons les appareils de test avec la dernière image de kernel et utilisons simpleperf pour capturer les flux d'exécution des instructions. Ce processus s'appuie sur les capacités matérielles pour enregistrer l'historique des branchements, en utilisant spécifiquement  ARM Embedded Trace Extension (ETE) et ARM Trace Buffer Extension (TRBE) sur les appareils Pixel.
  • Charges de travail : nous créons 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 collecter les données les plus précises possible, nous nous concentrons sur les points suivants :
    • Lancement d'applications : optimiser les délais les plus visibles pour l'utilisateur
    • Exploration d'applications basée sur l'IA : simuler des interactions utilisateur contiguës 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, nous capturons des modèles d'exécution haute fidélité qui représentent précisément l'interaction réelle des utilisateurs 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 de trace brutes 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 évite les régressions dans le code rarement utilisé et les augmentations inutiles de la taille binaire.

Étape 3 : Testez le profil

Avant le déploiement, les profils sont soumis à une validation rigoureuse pour s'assurer qu'ils offrent des gains de performances constants sans risque pour la stabilité.

  • Analyse du profil et du binaire : nous comparons strictement 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 de kernel. Cela confirme qu'il conserve 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 d'effectuer des mises à jour régulières :

  • Actualisation régulière : nous actualisons les profils dans les branches LTS du noyau Android avant chaque version de GKI, ce qui garantit que chaque build inclut les dernières données de profil.
  • 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 plus récentes de GKI, telles que 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 pour la 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, servant d'optimisation standard pour les bibliothèques de la plate-forme Android, ChromeOS et l'infrastructure de serveurs de Google depuis des années.

Pour garantir un comportement cohérent, nous appliquons une stratégie "prudente 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 garantit que les parties "froides" ou rarement exécutées du noyau se comportent exactement comme elles le feraient dans une compilation standard, ce qui évite les régressions de performances ou les comportements inattendus dans les cas limites.

Cap sur la suite

Nous déployons actuellement AutoFDO sur 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 sommes impatients 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 compatibilité actuelle avec aarch64.
  • Optimisation des modules GKI : actuellement, notre optimisation se concentre 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.
  • Compatibilité avec les modules de fournisseurs : nous souhaitons également prendre en charge AutoFDO pour les modules de fournisseurs créés à l'aide du Driver Development Kit (DDK). La compatibilité étant 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 de profil plus large : il est possible de collecter des profils à partir d'un plus grand nombre de critical user journeys (CUJ) pour les optimiser.

En intégrant AutoFDO au kernel 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.

Written by:
Continuer la lecture