Welche Optimierungen kann ich von Dalvik und dem Android-Toolchain?

stimmen
67

Ich arbeite an einer High-Performance-Android-Anwendung (ein Spiel), und obwohl ich zunächst versuchen, um die Lesbarkeit zu codieren, Ich mag ein Bild im Hinterkopf behalten, was unter der Haube geschieht. Mit C ++, habe ich eine ziemlich gute Intuition entwickelt, was der Compiler und nicht für mich tun. Ich versuche, das gleiche gilt für Java / Android zu tun.

Daher ist diese Frage. Ich konnte nur sehr wenig über dieses Thema im Web finden. Wird der Java-Compiler, Dalvik Konverter (dx) und / oder Jitter (auf Android 2.2 oder höher) ausführen Optimierungen wie folgt aus?

  • Verfahren inlining. Unter welchen Bedingungen? privateMethoden können immer sicher inlined werden; wird dies geschehen? Wie wäre es public finalMethoden? Methoden auf Objekte anderer Klassen? staticMethoden? Was passiert , wenn der Laufzeittyp des Objekts kann leicht durch den Compiler ableiten? Soll ich erklären Methoden wie finaloder staticwo immer möglich?

  • Gemeinsame subexpression Beseitigung. Zum Beispiel, wenn ich Zugriff auf someObject.someFieldzweimal, wird die Suche nur einmal durchgeführt werden? Was , wenn es ein Anruf zu einem Getter? Was passiert , wenn ich einen arithmetischen Ausdruck verwenden zweimal; wird es nur einmal bewertet werden? Was passiert , wenn ich das Ergebnis eines Ausdrucks verwenden, deren Wert ich weiß nicht zu ändern, da die obere Grenze einer forSchleife?

  • Die Überprüfung der Grenzen auf Array - Lookups. Wird die Werkzeugkette beseitigt dies unter bestimmten Bedingungen, wie die archetypische forSchleife?

  • Wert inlining. Werden Zugriffe auf einige public static final intimmer inlined werden? Selbst wenn sie in einer anderen Klasse sind? Selbst wenn sie in einem anderen Paket sind?

  • Die Verzweigungsvorhersage. Wie groß ist ein Thema, das auch? Ist Verzweigung eine große Leistung traf auf einem typischen Android-Gerät?

  • Eine einfache Rechnung. Wird someInt * 2ersetzt durch someInt << 1?

Und so weiter...

Veröffentlicht am 06/02/2011 um 11:18
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
103

Das ist Ben, einer der Ingenieure auf dem JIT @ Google arbeiten. Als Bill und ich an diesem Projekt begann, war das Ziel, eine Arbeits JIT so schnell wie möglich mit minimalen Auswirkungen auf liefern Behauptung Ressource (zB Speicherverbrauch, CPU vom Compiler Thread entführt), so dass es auf Low-End-Geräten ausgeführt werden kann als Gut. Deshalb haben wir eine sehr primitive Spur basiertes Modell. Das heißt, die Kompilierung Einheit an den JIT-Compiler übergeben ist ein Basisblock, manchmal so kurz wie ein einziger Befehl. Solche Spuren werden zusammen durch eine Technik namens Verkettungs zur Laufzeit genäht werden, so dass der Dolmetscher und Code-Cache-Suche wird nicht oft aufgerufen werden. Bis zu einem gewissen Grad der Beschleunigung der Hauptquelle kommt die wiederholten Dolmetscher aus der Beseitigung Kopf auf häufig ausgeführte Codepfade Parsen.

Das heißt, wir haben eine ganze Reihe von lokalen Optimierungen mit dem Froyo JIT implementiert:

  • Registerzuordnung (8 Register für v5te Ziel, da die JIT-Thumb-Code / 16 Register für v7 erzeugt)
  • Scheduling (zB redundante ld / st Eliminierung für Dalvik registriert, Lasthebe, speichern sinkend)
  • Redundant Check null Elimination (wenn eine solche Redundanz kann in einem Basisblock zu finden).
  • Schleifenbildung und Optimierung für einfache gezählten Schleifen (dh keinen Neben Ausgang in der Schleife). Für solche Schleifen Zugriffe auf ausgedehnte Induktionsvariablen basieren Array so optimiert, dass null und Bereichsprüfungen nur in dem Schleifenprolog durchgeführt werden.
  • Ein Eintrag Inline-Cache pro virtuellen callsite w / dynamisches Patching zur Laufzeit.
  • Guckloch-Optimierungen wie Power-Reduktion auf wörtliche Operanden für mul / div.

In Lebkuchen haben wir einfach inlining für Getter / Setter. Da die zugrunde liegenden JIT-Frontend noch einfacher Trace basiert ist, wenn der Angerufene Zweige dort hat, wird es nicht inlined werden. Aber der Inline-Cache-Mechanismus ist so implementiert, dass virtuelle Getter / Setter können problemlos inlined werden.

Wir arbeiten derzeit an der Erstellung Umfang über eine einfache Spur zu vergrößern, so dass der Compiler ein größeres Fenster für Code-Analyse und Optimierung hat. Bleib dran.

Beantwortet am 08/02/2011 um 08:20
quelle vom benutzer

stimmen
10

Ich bin sicher, dass meine Antwort nicht alle Ihre Fragen beantworten, aber ich denke, es ist ein Gewinn ist, wenn es auch nur eine beantwortet.

Sie scheinen ein tiefes Wissen über das Thema zu haben und wissen, was Sie wollen, so können Sie folgendes tun wollen. Erstellen Sie eine Beispielanwendung, die Aspekte enthält, die Sie wollen, zu untersuchen.

Nehmen Sie die APK Sie bekommen und es durch das laufen APK - Tool . Rückwärts Ihr eigener Code Engineering genau das zu tun , was Sie beabsichtigen , völlig in Ordnung ist , wie wir wissen.

Das APK Tool wird extrahieren und Ihre Ressourcen dekodieren und Reverse Engineering - .dexDateien .smaliDateien. Vielleicht mögen Sie das nachzuschlagen smali zu Projekt , um mehr Informationen zu erhalten , wie die zum Lesen von .smaliDateien und über seine Grenzen.

Wieder bin ich ziemlich sicher, dass dies nicht geht, alle Ihre Fragen zu beantworten, aber es könnte ein guter Anfang sein.

Beantwortet am 06/02/2011 um 13:28
quelle vom benutzer

stimmen
5

Zunächst möchte ich dieses Vorwort sagen, dass ich kein Experte für Dalvik bin, und einige meiner Antworten können falsch sein. Aber ich habe in den JIT-Code in Dalvik gegraben, und ich bin sehr vertraut mit dem Bytecode, der läuft Dalvik.

  1. Verfahren inlining - soweit ich weiß, dies geschieht nie. Ich bin fast sicher, es nie an der Bytecode-Ebene passiert, und ich glaube nicht, dass es an der JIT-Ebene geschieht zur Zeit - obwohl es vielleicht in der Zukunft.

  2. Gemeinsame subexpression Beseitigung - ich glaube, dass dies nur für Teilausdrücke durchgeführt werden würde, die verwenden keine nicht-final Variablen / Felder. Ich bin nicht ganz positiv, wenn es selbst dann passieren würde. Wenn es fertig ist, würde ich erwarten, dass es bei der Bytecode-Ebene getan werden, wahrscheinlich nicht die JIT-Ebene.

  3. Die Überprüfung der Grenzen auf Array-Lookups - keine Ahnung

  4. Wert inlining - Soweit ich weiß, ja - werden sie in all diesen Szenarien werden inlined.

  5. Die Verzweigungsvorhersage - nicht sicher,

  6. Eine einfache Rechnung - nicht so weit ich weiß,

Außerdem würde ich gerne einen anderen Weg der Annäherung an Sie nennen - dx und Dalvik sind beide Open Source, so dass Sie sie in alle Sie graben können. Obwohl, sind sie offensichtlich nicht klein Codebases, so ein gutes Stück Arbeit in ihnen auf dieser Ebene zu graben, nehmen würde

Beantwortet am 07/02/2011 um 04:29
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more