Chcę uruchomić intensywny program cpu w Pythonie na wielu rdzeniach i próbuję wymyślić, jak napisać rozszerzenia C, aby to zrobić. Czy są na tym jakieś próbki kodu lub samouczki?Jak używać rozszerzeń C w pytonie, aby ominąć GIL
Odpowiedz
Czy rozważałeś użycie jednej z bibliotek python mpi, takich jak mpi4py? Chociaż MPI jest zwykle używany do dystrybucji pracy w klastrze, działa całkiem dobrze na jednym komputerze wielordzeniowym. Minusem jest to, że będziesz musiał zreorganizować swój kod, aby korzystać z połączeń komunikacyjnych MPI (co może być łatwe).
Spójrz na multiprocessing. Jest to często pomijany fakt, że globalne udostępnianie danych, a nie wrzucanie mnóstwa wątków do jednego procesu, jest preferowane przez systemy operacyjne.
Jeśli nadal nalegasz, aby proces intensywnego działania wymagał gwintowania, zapoznaj się z dokumentacją dla working with the GIL in C. Jest to dość pouczające.
Już możesz przerwać program w Pythonie na wiele procesów. System operacyjny będzie już przydzielał twoje procesy do wszystkich rdzeni.
Zrób to.
python part1.py | python part2.py | python part3.py | ... etc.
System operacyjny zapewni, że część zużywa jak najwięcej zasobów. Możesz przesyłać informacje w sposób uproszczony wzdłuż tego potoku za pomocą cPickle
na sys.stdin
i sys.stdout
.
Bez zbytniej pracy może to często prowadzić do dramatycznych przyspieszeń.
Tak - dla haterza - możliwe jest skonstruowanie algorytmu tak torturowanego, że nie może być przyspieszony. Jednak często daje to ogromne korzyści przy minimalnej pracy.
.
Restrukturyzacja w tym celu zapewni dokładnie dopasowanie do restrukturyzacji wymaganej do maksymalizacji współbieżności wątków. Więc. Zacznij od równoległego procesu równoległego do momentu, w którym będziesz w stanie udowodnić, że współużytkowanie większej ilości danych pomógłoby, a następnie przejść do bardziej złożonego współdzielonego - wszystkiego, co łączy równoległość.
Jest to dobre wykorzystanie rozszerzenia C. Słowo kluczowe, które powinieneś wyszukać, to Py_BEGIN_ALLOW_THREADS
.
http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock
PS: Mam na myśli to, że jeśli przetwarzanie jest już w C, jak przetwarzanie obrazu, to zwolnij blokadę w rozszerzeniu C jest dobre. Jeśli twój kod przetwarzający jest głównie w Pythonie, sugestia innych osób do multiprocessing
jest lepsza. Zazwyczaj nie uzasadnia to przepisania kodu w C dla przetwarzania w tle.
Wieloprocesorowość jest łatwa. jeśli to nie jest wystarczająco szybkie, twoje pytanie jest skomplikowane.
Największy problem, jaki napotkałem podczas próby użycia wieloprocesowości w porównaniu do wątków, polega na tym, że próba uruchomienia ponad 1000 wątków (procesów) polega na tym, że każdy z nich otrzymuje oddzielne wystąpienie interpretera języka Python. Jest to niezwykle kosztowne pod względem pamięci. – Andy
@nalroff: To nie brzmi dobrze. Pamięć używana przez większość interpretera jest współdzielona przez wszystkie wystąpienia tego tłumacza. Tylko strony, które różnią się, zwiększają całkowite wykorzystanie pamięci. Upewnij się, że patrzysz na właściwą wartość.Warto również zauważyć, że procesy nie używają znacznie więcej pamięci niż dodatkowe wątki. –
W każdym przypadku, w którym użyłem modułu wieloprocesowego w Pythonie, zawsze widziałem dramatyczną różnicę w wykorzystaniu pamięci między procesami i wątkami. W każdym razie moduł wątków wydaje się być wystarczająco szybki do skradzionego przeglądania stron internetowych i testowania wydajności aplikacji internetowej, co jest wszystkim, czego używam. – Andy