Optimiser les performances thermiques et les performances des processeurs avec Android Dynamic Performance Framework

Ce guide explique comment utiliser Android Dynamic Performance Framework (ADPF) pour optimiser les jeux sur la base des fonctionnalités dynamiques de gestion de la température, des processeurs et des GPU sur Android. Bien que nous mettions ici l'accent sur les jeux, ces fonctionnalités peuvent également s'appliquer à d'autres applications haute performance.

ADPF est un ensemble d'API permettant aux jeux et aux applications haute performance d'interagir plus directement avec les systèmes d'alimentation et thermiques des appareils Android. Ces API vous offrent la possibilité de surveiller le comportement dynamique des appareils Android et d'optimiser les performances de jeu à un niveau durable sans provoquer de surchauffe des appareils.

Les SoC pour mobile et Android présentent des comportements plus dynamiques que les ordinateurs et les consoles. Parmi eux, citons la gestion de l'état thermique, des horloges variées pour le processeur et le GPU, ainsi que différents types de cœurs de processeur. À cela s'ajoute la topologie de plus en plus diversifiée des SoC. Il peut donc être difficile de s'assurer que votre jeu puisse exploiter ce comportement sans nuire aux performances des appareils. ADPF fournit certaines de ces informations pour améliorer la prévisibilité des performances.

Voici les principales fonctionnalités d'ADPF :

  • Surveillance de l'état thermique : suivez l'état thermique d'un appareil, puis ajustez les performances de manière proactive avant qu'il ne devienne instable.

  • Indices de performances du processeur : fournissez des indices de performances permettant à Android de choisir les horloges de processeur et les types de cœurs appropriés au lieu de se fier aux charges de travail précédentes.

  • Mode performances fixes : activez le mode performances fixes sur un appareil lors de l'analyse comparative afin d'obtenir des mesures qui ne sont pas modifiées par les horloges de processeur dynamiques.

Surveillance de l'état thermique

Disponible : à partir d'Android 11 (niveau d'API 30)
Obligatoire sur tous les appareils : Android 13 (niveau d'API 33) ou version ultérieure

Les performances potentielles de votre application sont limitées par l'état thermique de l'appareil, qui peut varier en fonction de caractéristiques telles que la météo, son utilisation récente et sa conception thermique. Les appareils ne peuvent maintenir des performances élevées que pendant une certaine durée avant de devoir faire face à des limites thermiques. L'un des buts ultimes de votre implémentation est d'atteindre les objectifs de performances sans dépasser les limites thermiques. En outre, lors du débogage des problèmes de performances, il est important de savoir quand l'état thermique d'un appareil limite les performances.

Les moteurs de jeu disposent généralement de paramètres de performances d'exécution permettant d'ajuster la charge de travail qu'ils imposent à l'appareil. Par exemple, ces paramètres peuvent définir le nombre de threads de calcul, l'affinité entre les nœuds de calcul et les threads pour les cœurs de petite et de grande taille, les options de fidélité GPU et les résolutions de tampon de trame.

Lorsqu'un appareil se rapproche d'un état thermique qui n'est pas sûr, ces paramètres contribuent à réduire la charge de travail afin que votre jeu n'ait pas à en subir les conséquences. Pour éviter toute limitation, vous devez surveiller l'état thermique de l'appareil et ajuster de manière proactive la charge de travail du moteur de jeu. Lorsque l'appareil est en surchauffe, la charge de travail doit descendre en dessous des niveaux de performances durables pour dissiper la chaleur.

PowerManager

ADPF fournit la classe PowerManager pour surveiller l'état thermique d'un appareil. En voici les principaux éléments :

Pour surveiller l'état thermique de l'appareil, interrogez la méthode getThermalHeadroom. Cette méthode détermine la durée pendant laquelle l'appareil peut maintenir le niveau de performances actuel sans surchauffe. Si cette durée est inférieure au temps nécessaire à l'exécution de la charge de travail, le jeu doit limiter la charge de travail à un niveau durable. Par exemple, il peut basculer sur des cœurs plus petits, diminuer la fréquence de frames ou réduire la fidélité.

Indices de performances du processeur

Disponibles : à partir d'Android 12 (niveau d'API 31)
Obligatoires sur tous les appareils : aucune version n'exige encore cette fonctionnalité

Grâce aux conseils sur les performances du processeur, le jeu peut influencer le comportement dynamique du processeur sans surchauffer l'appareil ni gaspiller de l'énergie. Sur la plupart des appareils, Android ajuste dynamiquement la vitesse d'horloge du processeur et le type de cœur d'une charge de travail en fonction des besoins antérieurs. Si une charge de travail utilise davantage de ressources de processeur, la vitesse d'horloge est augmentée, et la charge de travail finit par être transférée vers un cœur de plus grande taille. Si la charge de travail utilise moins de ressources, Android diminue l'allocation des ressources.

Vitesse d'horloge

Lorsque les appareils Android ajustent dynamiquement la vitesse d'horloge du processeur, la fréquence peut modifier l'impact de votre code en termes de performances. Il est important de concevoir du code qui s'adapte aux vitesses d'horloge dynamiques afin de maximiser les performances, de maintenir un état thermique sûr et d'optimiser la consommation d'énergie. Vous pouvez réduire temporairement les à-coups et augmenter la réactivité en exécutant votre jeu à des vitesses d'horloge maximales, mais cela draine la puissance et finit par entraîner la limitation thermique des horloges. Lorsque les horloges du processeur ou du GPU sont limitées, leurs performances ne suffisent pas à assurer le niveau de durabilité.

Vous ne pouvez pas attribuer directement des fréquences de processeur dans le code de votre application. Par conséquent, un moyen courant pour les applications de tenter de s'exécuter à des vitesses d'horloge de processeur plus élevées consiste à exécuter une boucle de disponibilité dans un thread d'arrière-plan afin que la charge de travail semble plus exigeante. Cette approche gaspille de l'énergie et augmente la charge thermique de l'appareil lorsque l'application n'utilise pas les ressources supplémentaires.

Types de cœurs

Les types de cœurs de processeur sur lesquels votre jeu s'exécute constituent un autre facteur de performances déterminant. Les appareils Android modifient souvent le cœur de processeur attribué à un thread de manière dynamique en fonction du comportement récent de la charge de travail. L'attribution des cœurs de processeur est encore plus complexe sur les SoC dotés de plusieurs types de cœurs. Sur certains de ces appareils, il n'est possible d'utiliser les cœurs de grande taille que brièvement pour ne pas passer à un état thermiquement intenable.

Il est déconseillé que votre jeu essaie de définir l'affinité du cœur de processeur pour les raisons suivantes :

  • Le type de cœur optimal pour une charge de travail varie selon le modèle de l'appareil.

  • La durabilité de l'exécution des cœurs de grande taille varie selon le SoC et les différentes solutions thermiques fournies par chaque modèle d'appareil.

  • L'impact environnemental sur l'état thermique peut compliquer davantage le choix des cœurs. Par exemple, la météo ou une coque de téléphone peut modifier l'état thermique d'un appareil.

  • La sélection des cœurs ne permet pas de prendre en charge de nouveaux appareils offrant des performances et des fonctionnalités thermiques supplémentaires. Par conséquent, les appareils ignorent souvent l'affinité du processeur d'un jeu.

PeformanceHintManager

ADPF fournit la classe PerformanceHintManager afin que les jeux puissent fournir des indices de performances à Android pour la vitesse d'horloge du processeur et le type de cœur. L'OS peut ainsi déterminer la meilleure façon d'utiliser ces indices en fonction du SoC et de la solution thermique de l'appareil. Si votre application utilise cette API avec la surveillance de l'état thermique, elle peut fournir des indices plus éclairés au système d'exploitation au lieu d'utiliser des boucles de disponibilité et d'autres techniques de codage pouvant entraîner des limitations.

Voici comment un jeu utilise les indices de performances :

  1. Créez des sessions d'indices pour les threads clés qui se comportent de la même manière. Exemple :

    • Les threads de rendu se voient attribuer une session.
    • Les threads d'E/S se voient attribuer une autre session.
    • Les threads audio se voient attribuer une troisième session.

    Le jeu doit effectuer cette tâche tôt, au moins 2 ms et de préférence plus de 4 ms avant qu'une session ne nécessite davantage de ressources système.

  2. Prévoyez la durée nécessaire pour exécuter chaque session pour chaque session d'indices. La durée habituelle équivaut à un intervalle de frames, mais l'application peut utiliser un intervalle plus court si la charge de travail ne varie pas de manière significative entre les frames.

Mode performances fixes

Disponible : à partir d'Android 11 (niveau d'API 30)
Obligatoire sur tous les appareils : aucune version n'exige encore cette fonctionnalité

Les appareils Android peuvent modifier les horloges de façon dynamique en fonction de la charge du système. Bien que ce comportement contribue à réaliser des économies d'énergie lors de l'utilisation, il ne facilite pas l'obtention de données de performances fiables. Si vous essayez de déterminer la vitesse à laquelle un fragment de code peut s'exécuter pour prévenir la régression, ou si une optimisation est reproductible, vos résultats ne seront pas fiables s'ils ne sont pas testés à des vitesses d'horloge fixes. Avec les horloges fixes, vous pouvez effectuer des tests A/B précis des performances sans que les modifications de la fréquence du processeur n'affectent les résultats.

Le mode performances fixes définit les horloges de processeur et de GPU avec des limites supérieure et inférieure. Ce mode ne désactive pas les autres comportements de performances dynamiques, tels que la sélection des cœurs.

Vous pouvez activer le mode performances fixes à l'aide de la commande adb suivante :

adb shell cmd power set-fixed-performance-mode-enabled [true|false]

Un appareil qui s'exécute en mode performances fixes peut quand même surchauffer, car ce mode ne place pas l'appareil dans un état thermiquement durable. C'est pourquoi nous vous recommandons de procéder comme suit pour les analyses comparatives :

  • Attendez que l'appareil retrouve son état thermiquement durable avant de lancer l'exécution.

  • Surveillez l'état thermique de l'appareil pendant les tests pour différencier l'impact entre le code de l'analyse comparative et les événements thermiques.

Application exemple

L'application exemple ADPF illustre l'utilisation de base de l'API ADPF. L'exemple affiche l'état thermique de l'appareil avec l'API getThermalHeadroom ADPF et l'API d'état thermique. L'application modifie également la charge de travail de manière dynamique en fonction de l'indice de l'API et de l'API PerformanceHintManager afin de contrôler les performances du thread de rendu.