r   e   k   l   a   m   a
r   e   k   l   a   m   a

Safari szybsze niż światło: kompilator LLVM w silniku przeglądarki Apple'a

Strona główna AktualnościOPROGRAMOWANIE

Najnowsze osiągnięcie programistów Apple'a pokazuje, że w kwestii zwiększania wydajności przeglądarek internetowych sporo jeszcze można zrobić. Jako pierwsi wbudowali oni w silnik przeglądarki Safari kompilator LLVM, jeszcze bardziej zacierając granice między językami interpretowanymi i kompilowanymi.

Kompilatory Just-In-Time (JIT) w silnikach skryptowych przeglądarek to już nic nowego – pierwszy pojawił się w Firefoksie w czasach, gdy Chrome było jeszcze na deskach kreślarskich. Pozwalają one na przekształcenie kodu w JavaScripcie na kod maszynowy już w trakcie jego uruchamiania, stosując rozmaite optymalizacje, by kod ten był wykonywany tak szybko, jak to możliwe. W miarę rozwoju kompilatorów JIT zaczęły one dorównywać złożonością tradycyjnym kompilatorom języków wysokiego poziomu Ahead-Of-Time (AOT). Jednocześnie rozwój aplikacji webowych doprowadził do tego, że zaczęły one dorównywać w złożoności aplikacjom desktopowym.

Programiści z Cupertino, pracując nad silnikiem WebKit, używanym w przeglądarkach Safari, starają się wprowadzać do kompilatora JIT JavaScriptu optymalizacje, które będą efektywne zarówno dla dynamicznych skryptów, które są szybko pobierane i uruchamiane w krótkim czasie, jak i dla dużych partii kodu, których fragmenty wykonywane są przez długi czas – np. silniki gier czy kodeki. W trakcie tej pracy zauważyli, że coraz częściej wynajdują koło na nowo, odtwarzając logikę stosowaną już od dziesięcioleci w kompilatorach AOT. Spostrzeżenie zaowocowało ciekawym pomysłem: a co, gdyby wykorzystać w silniku przeglądarki normalny, zaawansowany kompilator?

r   e   k   l   a   m   a

To co było tylko eksperymentem, zaowocowało przełomem w WebKicie. Do tej pory silnik skryptowy Apple'a działał w trzech etapach, zapewniających trzy poziomy wydajności uruchamianym na nim skryptom. Pierwszy z nich to interpreter LLInt, w którym skrypty uruchamiane były bez jakiejkolwiek kompilacji, natychmiastowo. Jeśli w skrypcie dana funkcja wywoływana była więcej niż sześć razy, albo jeśli dana pętla wykonywana była częściej niż sto razy, to wówczas kod trafiał do prostego kompilatora JIT (Baseline JIT), który bez jakichś szczególnych optymalizacji zwracał dla niej kod maszynowy, i tak działający co najmniej dziesięć razy szybciej, niż kod interpretowany. Jeśli jednak dana funkcja była wywoływana więcej niż 66 razy, lub pętla wykonywana więcej niż tysiąc razy, to trafiała do zaawansowanego kompilatora JIT (Data Flow Graph JIT, DFL), który stosując różne optymalizacje zwracał kod około trzykrotnie szybciej wykonywany, niż to, co był w stanie zwrócić podstawowy kompilator.

Do tych trzech poziomów doszedł teraz poziom czwarty, który w założeniu ma zapewnić taki poziom optymalizacji, jaki zapewniają kompilatory C czy C++. Ludzie Apple'a nazwali go FTL, co ma być skrótem od Fourth Tier LLVM („LLVM czwartego poziomu”), ale skojarzenia z Faster-Than-Light („szybciej-niż-światło”) są nieuchronne. Poziom czwarty powiela do pewnego stopnia ścieżkę optymalizacji zaawansowanego kompilatora JIT, ale jak widać na poniższym schemacie, po fazie wstępnych optymalizacji, zamiast uruchomić generator kodu maszynowego, przekształca już zoptymalizowane funkcje JavaScriptu do postaci SSA (single static assignment), w której każdej zmiennej wartość przypisuje się tylko raz, następnie przeprowadza dodatkowe optymalizacje, by wreszcie całość przekazać do kompilatora LLVM.

Jak wyjaśniają programiści WebKitu, LLVM został wybrany ze względu na zaawansowany, dojrzały do zastosowań produkcyjnych potok optymalizacyjny, w którym stosowane są tak pożądane mechanizmy jak zaawansowana alokacja rejestrów, zliczanie globalnych wartości i efektywny wybierak instrukcji. Pewnie nie bez znaczenia była też przyjazna dla biznesu otwarta licencja LLVM, tzw. NCSA Open Source License, która jest kombinacją licencji BSD i MIT/X11. Oprogramowanie wydane na takiej licencji można bez ograniczeń i dodatkowych obowiązków stosować w produktach komercyjnych. Minusem zastosowania LLVM jest jego relatywna powolność – kod, który produkuje jest bardzo szybki, ale sam proces kompilacji już taki szybki nie jest. By ograniczyć do minimum spowolnienia wywołane kombinacją, czwarty poziom kompilacji w WebKicie uruchamiany jest tylko dla funkcji, które wywoływane są naprawdę często, lub których uruchomienie zajmuje ponad 10 ms. Dodatkowo uruchamia się go w oddzielnym wątku, by aplikacja nie musiała czekać, w tym czasie stosując kod wygenerowany na poziomie trzecim.

Pierwsze benchmarki pokazują, że było to bardzo udane posunięcie. Dla skryptów napisanych w stworzonym przez Mozillę podzbiorze JavaScriptu asm.js, kod wykonywany przez FTL jest średnio 35% szybszy niż kod z DFL. Deweloperzy Apple'a podkreślają, że to dopiero początek optymalizacji, trzeba teraz powiększyć zbiór operacji JavaScriptu, które można kompilować FTL-em.

Efekty tej pracy już trafiły do najnowszych kompilacji WebKitu, dostępnych na stronie nightly.webkit.org. Niebawem pojawią się w stabilnych wersjach Safari, zarówno w wersji desktopowej tej przeglądarki, jak i wersji mobilnej dla iOS-a.

© dobreprogramy
r   e   k   l   a   m   a
r   e   k   l   a   m   a

Komentarze

r   e   k   l   a   m   a
r   e   k   l   a   m   a
Czy wiesz, że używamy cookies (ciasteczek)? Dowiedz się więcej o celu ich używania i zmianach ustawień.
Korzystając ze strony i asystenta pobierania wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.