Jakie są zalety kompilacji just-In-time w porównaniu z kompilacją ahead-of-time?

Ostatnio o tym myślałem i wydaje mi się, że większość zalet kompilacji JIT powinna być mniej więcej przypisana do formatu pośredniego, a jitting sam w sobie nie jest dobrym sposobem na wygenerowanie kodu.

Więc to są główne pro-JIT argumenty kompilacji, które zwykle słyszę:

  1. Kompilacja Just-In-time pozwala na większą przenośność. czy to nie jest związane z formatem pośrednim? To znaczy, nic nie powstrzymuje cię od kompilacji Wirtualnego kodu bajtowego do rodzimego kodu bajtowego po zainstalowaniu go na komputerze. Przenośność jest problemem w fazie "dystrybucji", a nie w fazie "uruchomionej".
  2. dobra, a co z generowaniem kodu w czasie wykonywania?To samo dotyczy. Nic nie stoi na przeszkodzie, aby zintegrować kompilator just-In-time dla prawdziwych potrzeb just-In-time z natywnym programem.
  3. ale runtime kompiluje go do kodu natywnego tylko raz i przechowuje wynikowy plik wykonywalny w jakimś buforze gdzieś na dysku twardym.Tak, pewnie. Ale to zoptymalizowało Twój program pod ograniczeniami czasowymi i nie czyni go lepszym od tego momentu. Zobacz następny akapit.

To nie jest tak, że przed czasem Kompilacja też nie miała żadnych zalet. Just-In-time Kompilacja ma ograniczenia czasowe: użytkownik końcowy nie może czekać w nieskończoność, gdy program zostanie uruchomiony, więc musi gdzieś się znaleźć kompromis. Przez większość czasu po prostu mniej optymalizują. Mój przyjaciel miał dowody profilowania , że wprowadzanie funkcji i rozwijanie pętli "ręcznie" (zaciemnianie kodu źródłowego w procesie) miało pozytywny wpływ na wydajność jego C# program do łamania liczb; robienie tego samego po mojej stronie, z moim C program wypełniający to samo zadanie, nie przyniosło żadnych pozytywnych rezultatów, i wierzę, że jest to spowodowane rozległymi transformacjami, które mój kompilator mógł wykonać.

A jednak jesteśmy otoczeni przez programy jitted. C # i Java są wszędzie, Skrypty Pythona mogą kompilować się do pewnego rodzaju kodu bajtowego i jestem pewien, że cała masa innych języków programowania robi to samo. Musi być dobry powód, dla którego mnie nie ma. Co sprawia, że kompilacja just-In-time jest tak lepsza od kompilacji Just-In-time?


EDIT aby wyjaśnić pewne zamieszanie, może byłoby ważne stwierdzenie, że jestem za pośrednią reprezentacją plików wykonywalnych. Ma to wiele zalet (i tak naprawdę większość argumentów dla kompilacji just-in-time to argumenty dla reprezentacji pośredniej). Moje pytanie dotyczy sposobu ich kompilacji do kodu natywnego.

Większość środowisk uruchomieniowych (lub kompilatorów) woli albo kompilować je just-in - time albo z wyprzedzeniem. Ponieważ ahead-of-time Kompilacja wygląda mi na lepszą alternatywę, ponieważ kompilator ma więcej czasu na wykonanie optymalizacji, zastanawiam się dlaczego Microsoft, Sun i wszyscy inni idą na odwrót. Mam trochę wątpliwości co do optymalizacji związanych z profilowaniem, ponieważ moje doświadczenie z just-In-time skompilowanymi programami wyświetliło słabe podstawowe optymalizacje.

Użyłem przykładu z kodem C tylko dlatego, że potrzebowałem przykładu kompilacji przed czasem kontra kompilacji just-In-time. Fakt, że kod C nie został wyemitowany do pośredniej reprezentacji jest nieistotny dla sytuacji, ponieważ wystarczy pokazać, że z wyprzedzeniem Kompilacja może przynieść lepsze natychmiastowe rezultaty.

Author: N J, 2010-01-21

9 answers

  1. Większa przenośność: pobyty (kod bajtowy) portable

  2. Jednocześnie bardziej specyficzne dla platformy: ponieważ JIT-kompilacja odbywa się na ten sam system, który działa kod, to może być bardzo, bardzo dopracowany do ten konkretny system. Jeśli tak przed czasem kompilacja (i jeszcze chcesz wysłać ten sam pakiet do wszyscy), trzeba iść na kompromis.

  3. Ulepszenia w technologii kompilatora mogą mieć wpływ na istniejących programów. A lepsze C kompilator wcale Ci nie pomaga z już wdrożonymi programami. A lepszy JIT-kompilator poprawi wydajność istniejących programów. Kod Javy, który napisałeś 10 lat temu, będzie działał szybciej.

  4. Dostosowując się do metryki czasu pracy. Kompilator JIT może nie tylko patrzeć na kod i system docelowy, ale również w jaki sposób kod jest używany. Może przyporządkować działający kod, oraz podejmowanie decyzji o optymalizacji według, Na przykład, co wartości parametrów metody Zwykle tak się składa, że tak.

Masz rację, że JIT dodaje do kosztów uruchomienia, a więc istnieje ograniczenie czasowe dla niego, natomiast kompilacja z wyprzedzeniem może zająć tyle czasu, ile chce. To sprawia, że bardziej odpowiednie dla aplikacji typu serwerowego, gdzie czas rozruchu nie jest tak ważny a" faza rozgrzewki " zanim kod zrobi się naprawdę szybki jest akceptowalna.

Przypuszczam, że możliwe byłoby przechowywanie wyniku kompilacji JIT gdzieś, tak aby mógł być ponownie użyty następnym razem. To daje kompilację "z wyprzedzeniem" dla drugiego uruchomienia programu. Może sprytni ludzie w Sun i Microsoft są zdania, że świeży JIT jest już wystarczająco dobry, a dodatkowa złożoność nie jest warta zachodu.

 31
Author: Thilo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 02:04:31

Strona ngen tool rozlała fasolę(lub przynajmniej zapewniła dobre porównanie obrazów natywnych z obrazami skompilowanymi JIT). Pliki wykonywalne, które są kompilowane z wyprzedzeniem, zazwyczaj mają następujące zalety:

  1. natywne obrazy ładują się szybciej, ponieważ nie mają zbyt wielu czynności startowych i wymagają statycznej ilości mniejszej pamięci (pamięci wymaganej przez kompilator JIT);
  2. Obrazy natywne mogą współdzielić kod biblioteki, podczas gdy obrazy skompilowane JIT nie mogę.

Just-In-time skompilowane pliki wykonywalne zazwyczaj mają przewagę w tych przypadkach:

  1. Obrazy natywne są większe niż ich odpowiednik bajtowy;
  2. Obrazy natywne muszą być regenerowane za każdym razem, gdy modyfikowany jest oryginalny skład lub jedna z jego zależności.

Potrzeba regeneracji obrazu, który jest przed czasem kompilowany za każdym razem, gdy jeden z jego składników jest ogromną wadą dla obrazów natywnych. Z drugiej strony fakt, że Skompilowane obrazy JIT nie mogą współdzielić kodu biblioteki może spowodować poważne uszkodzenie pamięci. System Operacyjny może załadować dowolną natywną bibliotekę w jednej fizycznej lokalizacji i udostępniać niezmienne jej części każdemu procesowi, który chce z niej korzystać, co prowadzi do znacznych oszczędności pamięci, zwłaszcza w przypadku RAM systemowych, których używa praktycznie każdy program. (Wyobrażam sobie, że jest to nieco zrównoważone faktem, że skompilowane programy JIT kompilują tylko to, czego faktycznie używają.)

Ogólna ocena Microsoft w tej kwestii jest to, że duże aplikacje zazwyczaj korzystają z kompilacji z wyprzedzeniem, podczas gdy małe zwykle nie.

 14
Author: zneak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-19 05:07:48

Prosta logika mówi nam, że skompilowanie ogromnego programu MS Office nawet z kodów bajtowych zajmie zbyt dużo czasu. Skończysz z ogromnym czasem rozpoczęcia, A to odstraszy każdego od Twojego produktu. Oczywiście, można wstępnie skompilować podczas instalacji, ale ma to również konsekwencje.

Innym powodem jest to, że nie wszystkie części aplikacji będą używane. JIT skompiluje tylko te części, na których zależy użytkownikowi, pozostawiając potencjalnie 80% kodu nietkniętego, oszczędzając czas i pamięć.

I wreszcie, kompilacja JIT może stosować optymalizacje, których nie potrafią normalni kompilatorzy. jak inlining wirtualnych metod lub części metod z trace trees. Co teoretycznie może sprawić, że będą szybsze.

 6
Author: vava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 01:59:23
  1. Lepsze wsparcie dla refleksji. Można to zrobić w zasadzie w skompilowanym programie, ale w praktyce prawie nigdy się to nie zdarza.

  2. Optymalizacje, które często można ustalić tylko poprzez dynamiczną obserwację programu. Na przykład, inlining funkcji wirtualnych, analiza ucieczki przekształcić alokacje stosu w alokacje sterty i zablokować coarsening.

 4
Author: dsimcha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 02:00:06

Jedną z zalet JIT, których nie widzę tutaj jest możliwość inline / optymalizacji w oddzielnych złożeniach / bibliotekach DLL / słoikach(dla uproszczenia będę używać "złożeń" od teraz).

Jeśli Twoja aplikacja odwołuje się do zestawów, które mogą ulec zmianie po instalacji (np. preinstalowane biblioteki, biblioteki frameworków, wtyczki), to model "compile-on-install" musi powstrzymać się od wprowadzania metod poza granice zestawu. W przeciwnym razie, gdy odwołany zespół jest aktualizowany musielibyśmy znaleźć wszystkie takie wbudowane bity kodu w odwołujących się zestawach w systemie i zastąpić je zaktualizowanym kodem.

W modelu JIT, możemy swobodnie inline między złożeniami, ponieważ zależy nam tylko na generowaniu poprawnego kodu maszynowego dla pojedynczego uruchomienia, podczas którego kod bazowy nie zmienia się.

 2
Author: ChaseMedallion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-05 18:33:02

Wydaje się, że idea ta została zaimplementowana w języku Dart:

Https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf

kompilacja JIT jest używana podczas programowania, przy użyciu kompilatora, który jest szczególnie szybki. Następnie, gdy aplikacja jest gotowa do wydania, jest kompilowany AOT. W związku z tym, przy pomocy zaawansowanych narzędzi i kompilatorów, Dart może dostarczyć najlepsze z obu światów: niezwykle szybkie cykle rozwoju oraz szybkie wykonanie i uruchomienie razy.

 2
Author: Aleksandr Ivannikov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 14:57:24

Może ma to związek z nowoczesnym podejściem do programowania. Wiesz, wiele lat temu pisałeś swój program na kartce papieru, inni ludzie zmieniali go w stos perforowanych kart i przekazywali do komputera, a jutro rano dostałbyś zrzut awaryjny na rolce papieru ważącej pół funta. Wszystko to zmusiło cię do dużo przemyśleń przed napisaniem pierwszej linijki kodu.

Te dni już dawno minęły. Przy użyciu języka skryptowego takiego jak PHP lub JavaScript, możesz natychmiast przetestować każdą zmianę. Tak nie jest w przypadku Javy, chociaż serwery aplikacji zapewniają wdrożenie na gorąco. Jest więc bardzo przydatne, że programy Java mogą być szybko kompilowane , ponieważ Kompilatory kodu bajtowego są dość proste.

Ale nie ma czegoś takiego jak języki tylko JIT. Kompilatory z wyprzedzeniem są dostępne dla Javy od dłuższego czasu, a ostatnio Mono wprowadziło je do CLR. W rzeczywistości, MonoTouch na możliwe w ogóle ze względu na kompilację AOT, ponieważ nie natywne aplikacje są zabronione w app store firmy Apple.

 1
Author: Dmitry Leskov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 05:57:49

Próbowałem to zrozumieć, ponieważ zobaczyłem, że Google zmierza w kierunku zastąpienia ich Dalvik Virtual Machine (zasadniczo inna maszyna wirtualna Java jak HotSpot) z Androidem Run Time (ART), który jest kompilatorem AOT, ale Java zwykle używa HotSpot, który jest kompilatorem JIT. Najwyraźniej ramię jest ~ 2x szybsze niż Dalvik... więc pomyślałem sobie: "dlaczego Java nie używa również AOT?". Tak czy inaczej, z tego co mogę się dowiedzieć, główną różnicą jest to, że JIT używa adaptacyjnych optymalizacja w czasie wykonywania, która (na przykład) pozwala na skompilowanie do kodu natywnego tylko tych części kodu bajtowego, które są często wykonywane; podczas gdy AOT kompiluje cały kod źródłowy do kodu natywnego, A Kod o mniejszej ilości działa szybciej niż Kod o większej ilości.
Muszę sobie wyobrazić, że większość aplikacji na Androida składa się z niewielkiej ilości kodu, więc średnio bardziej sensowne jest skompilowanie całego kodu źródłowego do kodu natywnego AOT i uniknięcie kosztów związanych od interpretacji / optymalizacji.

 1
Author: Scott Ferrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-07 16:54:46

Różnica między platform-browser-dynamic i platform-browser polega na sposobie kompilacji aplikacji angular. Korzystanie z dynamicznej platformy sprawia, że angular wysyła kompilator Just-In-Time Do front-endu, a także do aplikacji. Co oznacza, że Twoja aplikacja jest kompilowana po stronie klienta. Z drugiej strony, Korzystanie z platform-browser prowadzi do wcześniej skompilowanej wersji aplikacji jest wysyłany do przeglądarki. Co zwykle oznacza znacznie mniejszy pakiet wysyłane do przeglądarki. Angular2-dokumentacja do bootstrapowania w https://angular.io/docs/ts/latest/guide/ngmodule.html#! # bootstrap wyjaśnia to bardziej szczegółowo.

 0
Author: shubham chaturvedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-12 09:32:47