67 votes

Quelles optimisations puis-je attendre de Dalvik et l'Android de la chaîne?

Je suis en train de travailler sur une haute performance de l'application Android (un jeu), et bien que j'essaie de code pour plus de lisibilité d'abord, je tiens à garder dans le dos de mon esprit une image de ce qui se passe sous le capot. Avec le C++, j'ai développé une assez bonne intuition sur ce que le compilateur fait et ne pas faire pour moi. Je suis en train de faire la même chose pour Java/Android.

D'où cette question. J'ai pu trouver que très peu sur ce sujet sur le web. Sera le compilateur Java, Dalvik convertisseur (dx) et/ou de la Gigue (Android 2.2+) procéder à des optimisations comme la suivante?

  • Méthode inline. Sous quelles conditions? private méthodes peuvent toujours en toute sécurité être inline; cela sera fait? Que diriez - public final méthodes? Méthodes sur les objets des autres classes? static méthodes? Que faire si le moteur d'exécution type de l'objet peut être facilement déduite par le compilateur? Dois-je déclarer les méthodes qu' final ou static dans la mesure du possible?

  • Commune de la sous-expression de l'élimination. Par exemple, si j'ai accès someObject.someField deux fois, la recherche sera effectuée qu'une seule fois? Si c'est un appel à un getter? Que faire si j'utilise une expression arithmétique deux fois; il va être évaluées qu'une seule fois? Que faire si j'utilise le résultat d'une expression, dont la valeur que je connais pour ne pas changer, comme la limite supérieure d'un for boucle?

  • La vérification des limites sur la matrice de recherches. Sera le de la chaîne d'éliminer ce, dans certaines conditions, comme l'archétype for boucle?

  • La valeur inline. Auront accès à quelques - public static final int toujours être incorporé? Même s'ils sont dans une autre classe? Même s'ils sont dans un autre paquet?

  • Direction de la prévision. Comment un gros problème, est-ce la même? Est une ramification de grandes performances sur un appareil Android?

  • Un Simple calcul arithmétique. Va someInt * 2 être remplacé par someInt << 1?

Etc...

104voto

Ben Points 866

C'est Ben, l'un des ingénieurs travaillant sur le JIT @ Google. Lorsque le projet de Loi et j'ai commencé ce projet, l'objectif était d'offrir un travail JIT, dès que possible, avec un impact minimal sur les conflits de ressources (par exemple, de la mémoire, CPU détourné par le compilateur fil), de sorte qu'il peut fonctionner sur les bas de gamme des appareils en tant que bien. Par conséquent, nous avons utilisé un très primitives trace en fonction du modèle. Qui est, la compilation de l'entité passé au compilateur JIT est un bloc de base, parfois courte, comme une seule instruction. Ces traces sont cousues ensemble au moment de l'exécution grâce à une technique appelée le chaînage de sorte que l'interprète et le code de recherche dans le cache ne sera pas invoquée souvent. À un certain degré, la principale source de speedup vient de l'élimination de la répétition de l'interprète de l'analyse de surcharge sur les fréquemment exécutées chemins de code.

Cela dit, nous avons tout à fait quelques optimisations mises en œuvre avec l'Froyo JIT:

  • L'allocation de registres (8 registres pour v5te cible depuis le JIT produit Manette de code / 16 registres pour v7)
  • De la planification (par exemple redondant ld/st élimination de Dalvik registres, charge de levage, magasin de naufrage)
  • Redondant null vérification de l'élimination (si une telle redondance peut être trouvé dans un bloc de base).
  • La formation de la boucle et de l'optimisation pour la simple compté boucles (c'est à dire pas de face de sortie dans le corps de la boucle). Pour de telles boucles, des accès à des tableaux basés sur des étendues variables d'induction sont optimisés de sorte que la valeur null et la portée des vérifications sont effectuées uniquement dans la boucle prologue.
  • Une entrée inline cache par virtuel callsite w/ dynamique correctifs au moment de l'exécution.
  • Judas optimisations comme le pouvoir de réduction sur littérale opérandes pour mul/div.

Dans le pain d'épices, nous avons ajouté la simple inline pour les getters/setters. Depuis le sous-jacent JIT frontend est toujours simple de trace sur la base, si le destinataire de l'appel a des branches en y, il ne sera pas insérée. Mais la ligne de cache mécanisme est mis en œuvre pour que virtuel getters/setters peuvent être intégrées sans problème.

Nous sommes actuellement en train de travailler sur l'élargissement de la compilation de la portée au-delà d'une simple trace de sorte que le compilateur a une fenêtre plus grande pour l'analyse de code et optimisation. Restez à l'écoute.

10voto

Octavian Damiean Points 20620

Je suis sûr que ma réponse ne sera pas répondre à toutes vos questions, mais je suppose que c'est une victoire si elle répond à une question.

Vous semblez avoir une connaissance approfondie sur le sujet et savoir ce que vous voulez de sorte que vous pouvez effectuer les opérations suivantes. La construction d'un exemple d'application contenant les aspects que vous souhaitez étudier.

Prendre l'APK que vous obtenez et le lancer à travers l' APK de l'Outil. Reverse engineering de votre propre code pour faire tout ce que vous avez l'intention est parfaitement bien comme nous le savons.

L'APK Outil extraire et décoder vos ressources et désosser .dex fichiers d' .smali fichiers. Vous voudrez peut-être regarder la smali projet de trop pour obtenir plus d'informations sur la façon de lire l' .smali fichiers et sur ses limites.

Encore une fois je suis assez sûr que cela ne va pas répondre à toutes vos questions, mais il pourrait être un bon début.

5voto

JesusFreke Points 7447

Tout d'abord, permettez-moi de commencer en disant que je ne suis pas un expert sur dalvik, et certaines de mes réponses peut-être tort. Mais j'ai fouillé dans le JIT code dalvik, et je suis assez familier avec le bytecode que dalvik s'exécute.

  1. Méthode inline - autant que je sache, cela n'arrive jamais. Je suis quasiment sûre qu'il n'arrive jamais au niveau du bytecode, et je ne pense pas qu'il arrive à le JIT niveau d' - bien qu'il pourrait dans l'avenir.

  2. Commune de la sous-expression de l'élimination - je crois que cela ne le fait que pour les sous-expressions ne pas utiliser n'importe quel non-final variables et les champs. Je ne suis pas entièrement positive, si elle arriverait même à cette époque. Si c'est fait, je m'attends à ce qu'il soit fait au niveau du bytecode, probablement pas le JIT.

  3. La vérification des limites sur la matrice de recherches - aucune idée

  4. La valeur inline - autant Que je sache, oui, ils seront intégrées dans tous ces scénarios.

  5. Direction de la prévision - pas sûr

  6. Un Simple calcul arithmétique - pas autant que je le sache

Aussi, je tiens à mentionner une autre voie d'approche pour vous - dx et dalvik sont à la fois open source, donc vous pouvez creuser en eux tout ce que vous voulez. Bien que, manifestement, ils ne sont pas de petites bases de code, ce serait prendre juste un peu d'effort pour creuser en eux à ce niveau

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X