Dlaczego JVM jest oparty na stosie i w rejestrze maszyn wirtualnych Dalvik?

99

Jestem ciekawy, dlaczego firma Sun zdecydowała się na wykorzystanie stosu JVM, a Google zdecydował się na utworzenie rejestru DalvikVM?

Przypuszczam, że JVM nie może tak naprawdę zakładać, że pewna liczba rejestrów jest dostępna na platformie docelowej, ponieważ ma być niezależna od platformy. Dlatego po prostu odkłada alokację rejestru itp. Do kompilatora JIT. (Popraw mnie, jeśli się mylę.)

Więc faceci z Androidem pomyśleli: „hej, to nieefektywne, przejdźmy od razu do maszyny wirtualnej opartej na rejestrze…”? Ale czekaj, istnieje wiele różnych urządzeń z Androidem, jaką liczbę rejestrów wybrał Dalvik? Czy opkody Dalvik są zakodowane na stałe dla określonej liczby rejestrów?

Czy wszystkie obecne na rynku urządzenia z Androidem mają mniej więcej taką samą liczbę rejestrów? A może jest przeprowadzana ponowna alokacja rejestru podczas ładowania dex? Jak to wszystko do siebie pasuje?

aioobe
źródło
5
Czy to była decyzja Google'a, aby oprzeć się na rejestrze DalvikVM? Myślę, że DalvikVM został zaimplementowany zanim Google przejął Android Inc.
RoboAlex
1
Oczywiście masz rację. (Jednak niezbyt istotne dla pytania;)
aioobe

Odpowiedzi:

69

Istnieje kilka atrybutów maszyny wirtualnej opartej na stosie, które dobrze pasują do celów projektowych Javy:

  1. Projekt oparty na stosie zakłada bardzo niewiele założeń dotyczących sprzętu docelowego (rejestry, funkcje procesora), więc łatwo jest zaimplementować maszynę wirtualną na szerokiej gamie sprzętu.

  2. Ponieważ operandy instrukcji są w dużej mierze niejawne, kod wynikowy będzie zwykle mniejszy. Jest to ważne, jeśli zamierzasz pobierać kod przez wolne łącze sieciowe.

Korzystanie ze schematu opartego na rejestrach prawdopodobnie oznacza, że ​​generator kodu Dalvik nie musi pracować tak ciężko, aby wygenerować wydajny kod. Uruchomienie na architekturze wyjątkowo bogatej w rejestry lub ubogiej w rejestry prawdopodobnie utrudniłoby Dalvik, ale to nie jest zwykły cel - ARM jest architekturą pośrodku drogi.


Zapomniałem również, że pierwotna wersja Dalvik w ogóle nie zawierała JIT. Jeśli masz zamiar zinterpretować instrukcje bezpośrednio, schemat oparty na rejestrze jest prawdopodobnie zwycięzcą w zakresie interpretacji.

Mark Bessey
źródło
1
Ok, to interesujące. Czy zatem DalvikVM zakłada jakąkolwiek minimalną liczbę rejestrów na urządzeniu docelowym?
aioobe
1
Czytałem też, że niektórzy instalują Androida na swoich laptopach, ponieważ jest to „lekki” system operacyjny ... Wydaje się to złym pomysłem, jeśli laptop nie jest ARM i może ma architekturę z wieloma rejestrami?
aioobe
2
ok, właśnie się dowiedziałem, że kod bajtowy dex jest zdefiniowany w kategoriach nieskończonej maszyny rejestrującej, a jeśli chodzi o wydajność, wydaje się, że głównie dotyczy to pamięci.
aioobe
1
Nie pamiętałem, czy Dalvik był oparty na nieskończonych rejestrach, czy miał stały rozmiar pliku rejestru. Jeśli jest nieskończony, będzie działał optymalnie na architekturach, które mają „wystarczającą” liczbę rejestrów dla dowolnego uruchamianego kodu.
Mark Bessey
Bardziej szczegółowe wyjaśnienie można znaleźć tutaj: markfaction.wordpress.com/2012/07/15/…
noego
31

Nie mogę znaleźć odniesienia, ale myślę, że Sun zdecydował się na podejście oparte na kodzie bajtowym stosu, ponieważ ułatwia to uruchomienie maszyny JVM na architekturze z kilkoma rejestrami (np. IA32).

W Dalvik VM Internals z Google I / O 2008 twórca z Dalvik, Dan Bornstein, podaje następujące argumenty przemawiające za wyborem maszyny wirtualnej opartej na rejestrze na slajdzie 35 ze slajdów prezentacji :

Zarejestruj maszynę

Czemu?

  • unikaj wysyłania instrukcji
  • unikaj niepotrzebnego dostępu do pamięci
  • efektywnie wykorzystuj strumień instrukcji (wyższa gęstość semantyczna na instrukcję)

a na slajdzie 36:

Zarejestruj maszynę

Statystyki

  • 30% mniej instrukcji
  • 35% mniej jednostek kodu
  • 35% więcej bajtów w strumieniu instrukcji
    • ale możemy konsumować dwa naraz

Według Bornsteina jest to „ogólne oczekiwanie, jakie można znaleźć, konwertując zestaw plików klas na pliki dex”.

Odpowiednia część prezentacji wideo zaczyna się o 25:00 .

Istnieje również wnikliwy artykuł zatytułowany „Virtual Machine Showdown: Stack Versus Registers” autorstwa Shi et al. (2005) , który bada różnice między maszynami wirtualnymi opartymi na stosie i rejestrach.

Pływ
źródło
13

Nie wiem, dlaczego Sun zdecydował się oprzeć na stosie JVM. Maszyna wirtualna Erlangs BEAM jest oparta na rejestrach ze względu na wydajność. Dalvik również wydaje się być oparty na rejestrach ze względu na wydajność.

Z Pro Android 2 :

Dalvik używa rejestrów jako przede wszystkim jednostek przechowywania danych zamiast stosu. W rezultacie Google ma nadzieję wykonać o 30 procent mniej instrukcji.

A jeśli chodzi o rozmiar kodu:

Maszyna wirtualna Dalvik pobiera wygenerowane pliki klas Java i łączy je w jeden lub więcej plików wykonywalnych Dalvik (.dex). Ponownie wykorzystuje zduplikowane informacje z wielu plików klas, skutecznie zmniejszając zapotrzebowanie na miejsce (nieskompresowane) o połowę w porównaniu z tradycyjnym plikiem .jar. Na przykład plik .dex aplikacji przeglądarki internetowej w systemie Android ma około 200 KB, podczas gdy równoważna nieskompresowana wersja .jar to około 500 KB. Plik .dex budzika ma około 50 KB i jest mniej więcej dwa razy większy w wersji .jar.

I jak dobrze pamiętam Architektura komputera: podejście ilościowe pozwala również stwierdzić, że maszyna rejestrująca działa lepiej niż maszyna ze stosem.

Jonas
źródło
2
Gdybym miał zgadywać, powiedziałbym, że Sun zdecydował się oprzeć stos JVM, ponieważ jest łatwiejszy do wdrożenia niż maszyna rejestrująca. (Ale za niebanalnym kosztem wydajności, jak wspomniano tutaj.)
Mason Wheeler,
Nie mogę znaleźć odniesienia, ale myślę, że firma Sun zdecydowała się na podejście oparte na kodzie bajtowym opartym na stosie, ponieważ ułatwia to uruchomienie maszyny JVM w architekturze o niskim rejestrze.
Przepływ
1
W przypadku sprzętowego ISA tak, maszyny rejestrujące wygrały. Zasadniczo każdy procesor / mikrokontroler jest maszyną rejestrującą, ponieważ wszystko inne jest do niczego. Niektóre mają bardzo niewiele rejestrów, jak tylko akumulator i może jeden lub dwa rejestry wskaźnikowe lub indeksowe, ale to jeszcze bardziej przypomina maszynę rejestru w sensie teorii obliczeń. Ale mówimy o maszynach wirtualnych, które są interpretowane , więc „plik rejestru”, jeśli taki istnieje, faktycznie znajdowałby się w pamięci. Chyba że zostałeś skompilowany JIT do natywnego kodu maszynowego. Powody są bardzo różne, ponieważ reg jest szybszy niż stack.
Peter Cordes