Pytanie Języki i maszyny wirtualne: funkcje trudne do optymalizacji i dlaczego


Przeprowadzam ankietę dotyczącą funkcji przygotowujących do projektu badawczego.

Wymień główny język lub funkcję językową trudną do zoptymalizowania i dlaczego ta funkcja jest lub nie jest warta zapłaconej ceny, lub zamiast tego po prostu obalaj moje teorie poniżej z anegdotycznymi dowodami. Zanim ktokolwiek zakomunikuje to jako subiektywne, proszę o konkretne przykłady języków lub funkcji oraz pomysły na optymalizację tych funkcji lub ważne funkcje, których nie brałem pod uwagę. Również wszelkie odniesienia do implementacji, które potwierdzają moje teorie dobrze lub źle.

Najważniejsze na mojej liście trudnych do zoptymalizowania funkcji i moich teorii (niektóre z moich teorii są niesprawdzone i opierają się na eksperymentach myślowych):

1) Przeciążanie metody Runtime (zwany również wysyłką wielotorową lub wysyłką opartą na sygnaturach). Czy trudno jest zoptymalizować w połączeniu z funkcjami, które pozwalają na rekompilację środowiska wykonawczego lub dodawanie metod. A może to po prostu trudne? Wywoływanie pamięci podręcznej strony jest powszechną optymalizacją dla wielu systemów uruchomieniowych, ale wiele metod zwiększa dodatkową złożoność, a także sprawia, że ​​jest ona mniej praktyczna w przypadku metod wbudowanych.

2) Wpisz morfing / warianty (Znaki oparte na wartościach w przeciwieństwie do zmiennych) Tradycyjne optymalizacje po prostu nie mogą być zastosowane, gdy nie wiesz, czy coś może się zmienić w podstawowym bloku. W połączeniu z wieloma metodami, inlinowanie musi być wykonywane ostrożnie, jeśli w ogóle, i prawdopodobnie tylko dla danego progu wielkości osoby odwiedzającej. to znaczy. Łatwo jest rozważyć umieszczanie prostych pobrań własności (pobierających / ustawiających), ale wprowadzanie skomplikowanych metod może spowodować rozrost kodu. Drugim problemem jest to, że nie mogę po prostu przypisać wariantu do rejestru i JIT go do instrukcji natywnych, ponieważ muszę nosić ze sobą informacje o typie lub każda zmienna potrzebuje 2 rejestrów zamiast 1. Na IA-32 jest to niewygodne, nawet jeśli ulepszone z dodatkowymi rejestrami x64. Jest to prawdopodobnie moja ulubiona funkcja języków dynamicznych, ponieważ upraszcza tak wiele rzeczy z perspektywy programisty.

3) Kontynuacje pierwszej klasy - Istnieje wiele sposobów ich implementacji i zrobiłem to w obu najbardziej powszechnych podejściach, z których jeden to kopiowanie stosów, a drugi jako implementacja środowiska wykonawczego w celu użycia stylu przekazywania kontynuacji, stosów kaktusów, ramek stosu kopiowania przy zapisie, i zbieranie śmieci. Kontynuacje pierwszej klasy mają problemy z zarządzaniem zasobami, tj. musimy wszystko zapisać, na wypadek kontynuacji kontynuacji, i nie jestem świadomy, czy jakiekolwiek języki popierają kontynuację z "intencją" (tj. "Nie wrócę tu, więc możesz odrzucić tę kopię świata" ). Po zaprogramowaniu w modelu wątków i modelu contination, wiem, że oba mogą osiągnąć to samo, ale elegancja kontynuacji nakłada na środowisko wykonawcze znaczną złożoność, a także może wpływać na efektywność pamięci podręcznej (lokalizacja stosu zmienia się bardziej przy użyciu kontynuacji i rutyny ). Innym problemem jest to, że po prostu nie mapują sprzętu. Optymalizacja kontynuacji jest optymalizowana dla mniej powszechnego przypadku, a jak wiemy, wspólny przypadek powinien być szybki, a mniej powszechne przypadki powinny być poprawne.

4) Arytmetyka wskaźnikowa i umiejętność maskowania wskaźników (przechowywanie w liczbach całkowitych itp.) Musiałem to podać, ale mogłem bez problemu żyć bez tego.

Mam przeczucie, że wiele z cech wysokiego poziomu, szczególnie w dynamicznych językach po prostu nie mapuj na sprzęt. Implementacje mikroprocesorów mają miliardy dolarów badań za optymalizacją chipa, jednak wybór funkcji językowych może marginalizować wiele z tych funkcji (funkcje takie jak buforowanie, aliasing górnej części stosu do rejestracji, równoległość instrukcji, bufory adresów powrotu, pętla bufory i prognozy rozgałęzień). Makroprogramowe funkcje mikroprzedsiębiorstw niekoniecznie są rozwijane, jak niektórzy deweloperzy lubią myśleć, a implementacja wielu języków w VM kończy mapowanie rodzimych operacji na wywołania funkcji (tj. Im bardziej dynamiczny jest język, tym więcej musimy szukać / pamięć podręczna w czasie wykonywania, nic nie można założyć, więc nasz zestaw instrukcji składa się z wyższego odsetka nielokalnego rozgałęzienia niż tradycyjny, statycznie skompilowany kod) i jedyną rzeczą, którą możemy naprawdę JIT, jest ocena ekspresji typów niedynamicznych i operacje na stałych lub natychmiastowych typach. Mam wrażenie, że maszyny wirtualne i rdzenie JIT z bajtodu nie są z tego powodu zawsze uzasadnione dla niektórych języków.

Cieszę się z twoich odpowiedzi.


12
2018-03-24 22:57


pochodzenie


Może powinno być CW? - Norman Ramsey


Odpowiedzi:


Kilka komentarzy:

  • Wszystkie języki z dynamiczną wysyłką, nawet oparte na pojedynczym obiekcie, wydają się dość trudne do skutecznego wdrożenia. Spójrz na wszystkie wysiłki, które przeszły na optymalizację w czasie rzeczywistym Self (lub ostatnio, JavaScript, z SpiderMonkey).

  • Nie przeocz rozdzielone kontynuacje. Jury nadal jest nieobecne, ale są one znacznie łatwiejsze do zoptymalizowania niż klasyczne nieprzekonane kontynuacje. Przeczytaj artykuł Gasbichlera i Sperbera.


5
2018-03-24 23:26





To jest moje przeczucie, że kod bajtowy   Maszyny wirtualne i rdzenie JIT są   być może nie zawsze jest to uzasadnione   niektórych języków z tego powodu.

Czy IronPython nie został napisany, aby udowodnić, że maszyna wirtualna nie może zrobić tak dobrze, jak natywna implementacja języka (Python). A potem autor IronPython doznał szoku, gdy dowiedzieli się, że IronPython spisał się naprawdę dobrze dla dynamicznego języka na VM kodu bajtowego?

Własna własność Microsoft .Net internals jest zapisana jako stwierdzająca, że ​​ostatecznie uważają, że JITter przewyższy "normalny" kompilator / linker (na przykład C / C ++).

Sądzę, że ława przysięgłych nadal jest na to gotowa. Trudno to nazwać tak czy inaczej. Wybierz język, który najlepiej pasuje do zadania ...


1
2018-03-24 23:40



"Wybierz język, który najlepiej pasuje do zadania ..." - Dziękuję, zgadzam się, ale nie jest to celem mojego pytania. Dotyczy to w szczególności optymalizacji i funkcji. Jeśli chodzi o IronPython, nie znam odpowiedzi na twoje pytanie, ale chciałbym przeczytać, czy masz referencje, które mogę śledzić. - codenheim
Moje pytanie było retoryczne. IronPython był tak dobry, że obalił teorię, że języki dynamiczne nie są odpowiednie dla maszyn wirtualnych kodu bajtowego. Stąd następujący akapit o Microsoft, który obsługuje ten punkt widzenia. A to prowadzi do ostatniego akapitu. Obawa o to, czy odpowiedni język dynamiczny jest odpowiedni, nie ma sensu. Są (zakładając, że VM jest wystarczająco dobra, niektóre z nich nie są), więc możesz wybrać najlepszy język do pracy. - Stephen Kellett
To pytanie nie dotyczy tego, czy dany język jest odpowiedni, więc prosimy o zachowanie go w temacie. Jestem językiem i badaczem / realizatorem VM i mówię o konkretnych optymalizacjach funkcji i mówisz "wybierz najlepsze narzędzie do pracy". Piszę narzędzia do pracy. Teraz, do IronPython, jest to przydatny przykład, ale niektóre z wymienionych przeze mnie funkcji nie są obecne w Pythonie. Python nie ma rzeczywistych zamknięć (zmienne są tylko do odczytu) lub pierwszej klasy kontynuacji (CPS to nie to samo). IronPython udowadnia, że ​​Python może być dobrze zaimplementowany w środowisku CLR, a nie we wszystkich językach. - codenheim
IronRuby to kolejny dynamiczny język, który jest także szybszy w DLR niż natywna wersja: antoniocangiano.com/2009/08/03/... Masz też JRuby, Groovy, Lua (i LuaJIT). Nie zamierzam próbować obalić twoich pomysłów - nie używam języków dynamicznych na tyle, aby mieć wystarczająco silną opinię na ich temat, nie mówiąc już o napisaniu VM je implementującej. Facet o imieniu Mike Pall utrzymuje projekt Lua JIT. Jest bardzo przystępny - możesz znaleźć dla niego kopalnię doświadczeń i opinii na temat różnych technik. - Stephen Kellett
IronRuby to inny język oparty na CLR / DLR, który nie jest (jeszcze) pełną implementacją edycji referencyjnej, ani wszystkimi funkcjami, o których wspomniałem powyżej (przynajmniej z tego co wiem). Ale dzięki za komentarze. - codenheim