Python i GIL: udawajmy, że problemu nie ma

2010-07-28

Guido van Rossum w przemyśleniach:

Their prediction is that as machines with many processing cores become more prevalent, the relevant architecture will change from cores sharing a single coherent memory (the model on which threads are based) to one where each core has a limited amount of private memory, and communication is done via message passing between the cores. This gives them (and me :-) hope that the GIL won't be a problem as long as we adopt a parallel processing model.

To bardzo naciągane przewidywanie, zważywszy na to, że dziś nie da się kupić żadnego komputera[1] o takiej architekturze, zaś wszyscy z powodzeniem budują architektury SMP ze współdzieloną spójną pamięcią. Jak widać też na przykładzie maszyn Azul, takie architektury skalują się do setek procesorów: od Azul można kupić maszynę z 864 rdzeniami. Owszem, w przyszłości prawdopodobnie będzie konieczne odejście od modelu spójnej pamięci, ale mówimy tu o przyszłości odległej o 10 lat lub więcej.

Te przewidywania wyglądają więc na zmiatanie problemu GIL (Global Interpreter Lock) pod szafę.

Dla tych, którzy uważają problem jednowątkowości Pythona za wyimaginowany: w Fablo nasz kod działa równolegle na maszynach wieloprocesorowych i nie wyobrażamy sobie równoległości wyłącznie w niektórych bibliotekach. Używamy pojedynczych wątków lub wielu pul z wątkami na różne sposoby i w wielu miejscach. Gdybyśmy mieli pisać Fablo w Pythonie, to GIL byłby poważnym problemem wydajnościowym.

[1] Dostępnego dla normalnych ludzi.


Komentarze

A ja zgadzam się z Brucem Eckelem, że model wątków jest po prostu "BROKEN". Debugowanie takich aplikacji to koszmar, biblioteki Javowe które gdzieś tam sobie na boku mają swoje wątki powodują różne niezdefiniowane zachowanie. Dobry model to architektura shared-nothing i właśnie message-passing (ale nie na poziomie architektury CPU, tylko jakieś sockety czy pipe'y). Na linuksie CPython bardzo dobrze sobie radzi z multiprocessing i wieloma zwykłymi procesami systemowymi (które właśnie pod Linuksem nie są mniej wydajne od wątków). Dodatkowo pod Linuksem jak forkuje się procesy, to pamięć procesów działa w trybie "copy-on-write", co oznacza że np. jeżeli mamy do przerobienia równolegle listę rekordów, to po stworzeniu wielu procesów fizycznie nadal mamy jedną listę w pamięci (o ile tej listy nie modyfikujemy).

No i GIL jest cechą konkretnej implementacji Pythona - CPythona, jak ktoś koniecznie chce wątki to niech weźmie JPythona czy IronPythona. GIL ma też zaletę - kod interpretera jest dzięki niemu dużo prostszy i dużo łatwiej pisać rozszerzenia w C.

Artur S.2010-07-29

Jeszcze jedna notka, bo coś widzę dyskusja się nie rozwija zbyt dynamicznie ;).

Błąd widzę w podejściu charakterystycznym dla świata Javowego, gdzie równoległość utożsamia się z wątkami. A to tylko jeden z modeli równoległości, z wieloma wadami i ograniczeniami (np. skalowalność ograniczona do jednego node'a, w przeciwieństwie do wiekszości rozwiązań opartych na message-passing). Nie bez powodu Erlang, język zaprojektowany do masowego równoległego przetwarzania, używany z sukcesem do zadań mission-critical, nie ma w ogóle wątków, a jedynie architekturę message-passing & shared-nothing. Takie coś można bez ograniczeń wydajnościowych stosować w CPythonie z użyciem modułu multiprocessing (w ramach jednego node'a). Cięższe rozwiązanie skalowalne na wiele node'ów i w dużej mierze niezależne od języka programowania, to stosowanie kolejek wiadomości (AMQP, JMS).

Artur S.2010-07-29

Artur: to nie wątki są problemem, tylko narzędzia synchronizacyjne i struktury danych. Zgadzam się, że pisanie i debugowanie aplikacji wielowątkowych w Javie to koszmar. Ale już np. w Clojure — absolutnie nie.

W Fablo mamy dziesiątki wątków (ile konkretnie to zależy od ilości procesorów) i nie są one żadnym problemem. Co więcej, nie mamy ani jednego semafora. Kod zbudowany jest za pomocą świetnych struktur danych Clojure oraz narzędzi synchronizacyjnych (atoms, agents, refs).

Twierdzenie, że to wątki są "BROKEN", to zmiatanie problemu pod szafę. Wątki to takie procesy, tylko lżejsze.

Piszesz o "skalowalności ograniczonej do jednego node'a" — ale przecież taki "node" ma obecnie około 16 procesorów! (w przypadku Azul - 864 :)) Nie można tego ignorować.

Co zaś się tyczy przekazywania komunikatów, to zgadzam się, że to krok do przodu — ale ostrożnie. Takie architektury mają swoje problemy, np. bardzo łatwo jest doprowadzić do blokady. Przy użyciu narzędzi Clojure jest to naprawdę trudne.

Jan Rychter2010-07-30