Warum basiert der JVM-Stack und der Dalvik VM auf Registern?

97

Ich bin gespannt, warum Sun beschlossen hat, die JVM stapelbasiert zu machen, und Google beschlossen hat, die DalvikVM registrierungsbasiert zu machen.

Ich nehme an, die JVM kann nicht wirklich davon ausgehen, dass eine bestimmte Anzahl von Registern auf der Zielplattform verfügbar ist, da sie plattformunabhängig sein soll. Daher verschiebt es einfach die Registerzuordnung usw. an den JIT-Compiler. (Korrigieren Sie mich, wenn ich falsch liege.)

Also dachten die Android-Leute: "Hey, das ist ineffizient, lass uns gleich eine registrierungsbasierte VM wählen ..."? Aber warten Sie, es gibt mehrere verschiedene Android-Geräte. Auf wie viele Register hat der Dalvik abgezielt? Sind die Dalvik-Opcodes für eine bestimmte Anzahl von Registern fest codiert?

Haben alle aktuellen Android-Geräte auf dem Markt ungefähr die gleiche Anzahl von Registern? Oder wird während des Dex-Ladens eine Neuzuweisung des Registers durchgeführt? Wie passt das alles zusammen?

aioobe
quelle
5
War das die Entscheidung von Google, das DalvikVM registrierungsbasiert zu machen? Ich denke, DalvikVM wurde implementiert, bevor Google die Android Inc.
RoboAlex
1
Du hast natürlich recht. (Nicht sehr relevant für die Frage;)
Aioobe

Antworten:

67

Es gibt einige Attribute einer stapelbasierten VM, die gut zu den Entwurfszielen von Java passen:

  1. Ein stapelbasiertes Design macht nur sehr wenige Annahmen über die Zielhardware (Register, CPU-Funktionen), sodass es einfach ist, eine VM auf einer Vielzahl von Hardware zu implementieren.

  2. Da die Operanden für Anweisungen weitgehend implizit sind, ist der Objektcode tendenziell kleiner. Dies ist wichtig, wenn Sie den Code über eine langsame Netzwerkverbindung herunterladen möchten.

Die Verwendung eines registergestützten Schemas bedeutet wahrscheinlich, dass der Codegenerator von Dalvik nicht so hart arbeiten muss, um performanten Code zu erzeugen. Das Laufen auf einer extrem registerreichen oder registerarmen Architektur würde Dalvik wahrscheinlich behindern, aber das ist nicht das übliche Ziel - ARM ist eine Architektur mitten auf der Straße.


Ich hatte auch vergessen, dass die ursprüngliche Version von Dalvik überhaupt keine JIT enthielt. Wenn Sie die Anweisungen direkt interpretieren möchten, ist ein registergestütztes Schema wahrscheinlich ein Gewinner für die Interpretationsleistung.

Mark Bessey
quelle
1
Ok, das ist interessant. Nimmt die DalvikVM also eine minimale Anzahl von Registern auf dem Zielgerät an?
Aioobe
1
Außerdem habe ich gelesen, dass einige Leute Android auf ihren Laptops installieren, da es sich um ein "leichtes" Betriebssystem handelt ... Das scheint eine schlechte Idee zu sein, wenn der Laptop kein ARM ist und möglicherweise eine Architektur mit vielen Registern hat?
Aioobe
2
ok, ich habe gerade erfahren, dass Dex-Bytecode als unendliche Registermaschine definiert ist, und wenn es um Effizienz geht, scheint es hauptsächlich um Speicherplatz zu gehen.
Aioobe
1
Ich konnte mich nicht erinnern, ob Dalvik auf einem unendlichen Register basierte oder eine feste Registerdateigröße hatte. Wenn es unendlich ist, funktioniert es in der Regel optimal für Architekturen, die "genug" Register für den von Ihnen ausgeführten Code haben.
Mark Bessey
Eine ausführlichere Erklärung finden Sie hier: markfaction.wordpress.com/2012/07/15/…
noego
30

Ich kann keine Referenz finden, aber ich denke, Sun hat sich für den stapelbasierten Bytecode-Ansatz entschieden, da es einfach ist, die JVM auf einer Architektur mit wenigen Registern (z. B. IA32) auszuführen.

In Dalvik VM Internals von Google I / O 2008 gibt der Dalvik-Ersteller Dan Bornstein die folgenden Argumente für die Auswahl einer registergestützten VM auf Folie 35 der Präsentationsfolien an :

Maschine registrieren

Warum?

  • Anweisungsversand vermeiden
  • Vermeiden Sie unnötigen Speicherzugriff
  • Befehlsstrom effizient verbrauchen (höhere semantische Dichte pro Befehl)

und auf Folie 36:

Maschine registrieren

Die Statistiken

  • 30% weniger Anweisungen
  • 35% weniger Codeeinheiten
  • 35% mehr Bytes im Anweisungsstrom
    • aber wir dürfen zwei gleichzeitig konsumieren

Laut Bornstein ist dies "eine allgemeine Erwartung, die Sie finden könnten, wenn Sie eine Reihe von Klassendateien in Dex-Dateien konvertieren".

Der relevante Teil des Präsentationsvideos beginnt um 25:00 Uhr .

Es gibt auch ein aufschlussreiches Papier mit dem Titel "Virtual Machine Showdown: Stapel versus Register" von Shi et al. (2005) , in dem die Unterschiede zwischen stapel- und registergestützten virtuellen Maschinen untersucht werden.

Fließen
quelle
13

Ich weiß nicht, warum Sun beschlossen hat, JVM-Stack-basiert zu machen. BEANGs virtuelle Maschine, BEAM ist aus Leistungsgründen registrierungsbasiert. Und Dalvik scheint auch aus Leistungsgründen registrierungsbasiert zu sein.

Von Pro Android 2 :

Dalvik verwendet Register hauptsächlich als Datenspeichereinheiten anstelle des Stapels. Google hofft, dadurch 30 Prozent weniger Anweisungen zu erhalten.

Und zur Codegröße:

Die Dalvik-VM nimmt die generierten Java-Klassendateien und kombiniert sie zu einer oder mehreren Dalvik Executables-Dateien (.dex). Es verwendet doppelte Informationen aus mehreren Klassendateien wieder und reduziert so den Platzbedarf (unkomprimiert) gegenüber herkömmlichen JAR-Dateien um die Hälfte. Beispielsweise beträgt die .dex-Datei der Webbrowser-App in Android ungefähr 200 KB, während die entsprechende unkomprimierte .jar-Version ungefähr 500 KB beträgt. Die .dex-Datei des Weckers ist ungefähr 50.000 und in der .jar-Version ungefähr doppelt so groß.

Und wie ich mich erinnere Computer-Architektur: Ein quantitativer Ansatz kommt auch zu dem Schluss, dass eine Registermaschine eine bessere Leistung als eine stapelbasierte Maschine aufweist.

Jonas
quelle
2
Wenn ich raten müsste, würde ich sagen, dass Sun beschlossen hat, den JVM-Stack basierend zu machen, da er einfacher zu implementieren ist als ein Registercomputer. (Aber zu einem nicht trivialen Leistungspreis, wie hier angegeben.)
Mason Wheeler
Ich kann keine Referenz finden, aber ich denke, Sun hat sich für den stapelbasierten Bytecode-Ansatz entschieden, da es einfach ist, die JVM auf einer Architektur mit niedrigen Registern auszuführen.
Flow
1
Für eine Hardware-ISA haben ja Registermaschinen gewonnen. Grundsätzlich ist jede CPU / Mikrocontroller eine Registermaschine, weil alles andere im Vergleich scheiße ist. Einige haben nur sehr wenige Register, wie nur einen Akkumulator und vielleicht ein oder zwei Zeiger- oder Indexregister, aber das ist immer noch eher eine Registermaschine im Sinne der Berechnungstheorie. Es handelt sich jedoch um interpretierte VMs , sodass sich die "Registerdatei", falls vorhanden, tatsächlich im Speicher befindet. Es sei denn, Sie haben JIT-kompiliert zu nativem Maschinencode. Die Gründe dafür sind sehr unterschiedlich, dass reg schneller als Stack ist.
Peter Cordes