Dlaczego w wirtualnej maszynie Javy nie ma GIL? Dlaczego Python tak bardzo go potrzebuje?

177

Mam nadzieję, że ktoś może udzielić pewnego wglądu w to, co zasadniczo różni się w wirtualnej maszynie Java, która pozwala jej ładnie implementować wątki bez potrzeby globalnej blokady interpretera (GIL), podczas gdy Python wymaga takiego zła.

AgentLiquid
źródło

Odpowiedzi:

223

Python (język) nie potrzebuje GIL (dlatego można go doskonale zaimplementować na JVM [Jython] i .NET [IronPython], a te implementacje swobodnie wielowątkowe). CPython (popularna implementacja) zawsze używał GIL dla łatwości kodowania (zwłaszcza kodowania mechanizmów zbierania śmieci) i integracji nie-bezpiecznych dla wątków bibliotek kodowanych w C (kiedyś było ich mnóstwo; -).

Projekt Unladen Swallow , oprócz innych ambitnych celów, planuje maszynę wirtualną wolną od GIL dla Pythona - cytując tę ​​witrynę: „Ponadto zamierzamy usunąć GIL i naprawić stan wielowątkowości w Pythonie. Uważamy, że jest to możliwe dzięki wdrożeniu bardziej wyrafinowanego systemu GC, czegoś w rodzaju Recycler firmy IBM (Bacon et al, 2001). "

Alex Martelli
źródło
6
Alex, a co ze starymi próbami usunięcia GIL, czy nie było z tym wiele narzutów (pamiętam współczynnik 2)?
Bartosz Radaczyński
10
Tak, Bartosz, Greg Stein zmierzył to w 1999 roku. Zbieranie śmieci przez liczenie referencyjne było zabójcą, wymuszając ogromne obciążenie drobnoziarnistego blokowania. Dlatego tak ważny jest bardziej zaawansowany GC.
Alex Martelli
80
Zespół Unladen Swallow zrezygnował z usunięcia GIL: code.google.com/p/unladen-swallow/wiki/ ...
Seun Osewa
1
Alternatywami dla Unloaden i CPython są PyPy, Jython i IronPython. Te dwa ostatnie nie mają GIL, ale użycie modułu wieloprocesorowego omija GIL i jest bezpieczniejsze.
Cees Timmerman
50

JVM (przynajmniej hotspot) ma podobną koncepcję do "GIL", jest po prostu znacznie drobniejszy w swojej szczegółowości blokad, większość pochodzi z GC w hotspotach, które są bardziej zaawansowane.

W CPythonie jest to jedna duża blokada (prawdopodobnie nie do końca prawda, ale wystarczająco dobra ze względu na argumenty), w JVM jest bardziej rozpowszechniona z różnymi koncepcjami w zależności od tego, gdzie jest używana.

Spójrz na przykład na vm / runtime / safepoint.hpp w kodzie hotspotu, który jest efektywną barierą. W bezpiecznym punkcie cała maszyna wirtualna zatrzymała się w odniesieniu do kodu java, podobnie jak maszyna wirtualna Pythona zatrzymuje się na GIL.

W świecie Javy takie zdarzenia wstrzymania maszyny wirtualnej są znane jako „stop-the-world”, w tych miejscach tylko kod natywny powiązany z określonymi kryteriami działa swobodnie, a reszta maszyny wirtualnej została zatrzymana.

Również brak zgrubnej blokady w Javie znacznie utrudnia pisanie JNI, ponieważ JVM daje mniej gwarancji dotyczących swojego środowiska dla wywołań FFI, co jest jedną z rzeczy, które cpython sprawia, że ​​jest dość łatwa (chociaż nie tak łatwa jak używanie ctypów).

Greg Bowyer
źródło
7

Poniżej znajduje się komentarz w tym poście na blogu http://www.grouplens.org/node/244 który wskazuje, dlaczego tak łatwo zrezygnować z GIL dla IronPython lub Jython, jest tak, że CPython używa liczenia referencji, podczas gdy pozostałe 2 maszyny wirtualne mają odśmiecanie pamięci.

Nie rozumiem dokładnej mechaniki, dlaczego tak jest, ale brzmi to jak wiarygodny powód.

user235859
źródło
5
Kiedy w rozwiązły sposób udostępniasz obiekty między wątkami, ćwiczenie, gdy nikt nie ma już odniesienia do określonego obiektu, jest umiarkowanie niezręczne. Liczenie referencji z blokadą globalną to jeden (drogi) sposób. Innym sposobem rozwiązania tego problemu byłoby pozostawienie tylko jednego wątku na raz na przechowywanie odwołań do obiektu, co spowodowałoby, że większość działań byłaby lokalna w wątku, kosztem utrudniającej komunikację między wątkami. Osobiście uważam, że jest to wymowne, że HPC wykorzystuje przekazywanie komunikatów między procesorami, a nie pamięć współdzieloną, i że robi to ze względu na skalowalność ...
Donal Fellows
0

W tym linku mają następujące wyjaśnienie:

... "Części Interpretera nie są bezpieczne dla wątków, chociaż głównie dlatego, że uczynienie ich wszystkich bezpiecznymi wątkami przez masowe użycie blokad spowolniłoby bardzo pracę jednowątkową ( źródło ). Wydaje się, że jest to związane z wyrzucaniem elementów bezużytecznych w CPython korzystającym z liczenia odwołań (JVM a CLR nie, i dlatego nie ma potrzeby blokowania / zwalniania liczby referencji za każdym razem). Ale nawet gdyby ktoś wymyślił akceptowalne rozwiązanie i wdrożył je, biblioteki innych firm nadal miałyby te same problemy ”.

Oliver Wilken
źródło
-1

Pythonowi brakuje jit / aot, a ramy czasowe, w których został napisany na procesorach wielowątkowych, nie istniały. Alternatywnie możesz ponownie skompilować wszystko w języku Julia lang, któremu brakuje GIL, i przyspieszyć działanie kodu Pythona. Jython jest do bani, wolniejszy niż Cpython i Java. Jeśli chcesz pozostać przy Pythonie, rozważ użycie równoległych wtyczek, nie uzyskasz natychmiastowego przyspieszenia, ale możesz wykonać programowanie równoległe za pomocą odpowiedniej wtyczki.

Jim
źródło
a co z PyPy?
denis631