W przypadku C ++ możemy użyć OpenMP do programowania równoległego; jednak OpenMP nie będzie działać dla Pythona. Co powinienem zrobić, jeśli chcę równolegle z niektórymi częściami mojego programu w języku Python?
Strukturę kodu można uznać za:
solve1(A)
solve2(B)
Gdzie solve1
i solve2
są dwie niezależne funkcje. Jak uruchomić ten rodzaj kodu równolegle zamiast po kolei, aby skrócić czas wykonywania? Mam nadzieję, że ktoś może mi pomóc. Z góry bardzo dziękuję. Kod to:
def solve(Q, G, n):
i = 0
tol = 10 ** -4
while i < 1000:
inneropt, partition, x = setinner(Q, G, n)
outeropt = setouter(Q, G, n)
if (outeropt - inneropt) / (1 + abs(outeropt) + abs(inneropt)) < tol:
break
node1 = partition[0]
node2 = partition[1]
G = updateGraph(G, node1, node2)
if i == 999:
print "Maximum iteration reaches"
print inneropt
Gdzie setinner i setouter to dwie niezależne funkcje. Właśnie tam chcę równolegle ...
python
parallel-processing
ilovecp3
źródło
źródło
Odpowiedzi:
Możesz użyć modułu wieloprocesorowego . W tym przypadku mogę użyć puli przetwarzania:
Spowoduje to powstanie procesów, które mogą wykonywać za Ciebie ogólną pracę. Ponieważ nie przeszliśmy
processes
, spowoduje to powstanie jednego procesu dla każdego rdzenia procesora na twojej maszynie. Każdy rdzeń procesora może jednocześnie wykonywać jeden proces.Jeśli chcesz zmapować listę do pojedynczej funkcji, wykonaj następujące czynności:
Nie używaj wątków, ponieważ GIL blokuje wszelkie operacje na obiektach Pythona.
źródło
pool.map
akceptuje również słowniki jak args? Czy tylko proste listy?Dzięki Rayowi można to zrobić bardzo elegancko .
Aby zrównoleglać swój przykład, musisz zdefiniować swoje funkcje za pomocą
@ray.remote
dekoratora, a następnie wywołać je za pomocą.remote
.W porównaniu z modułem wieloprocesowym ma to wiele zalet .
Te wywołania funkcji można składać razem, np.
Zauważ, że Ray to framework, który pomagałem rozwijać.
źródło
pip
. Proponuję spróbowaćpip install --upgrade pip
. Jeślisudo
w ogóle musisz używać , możliwe, że wersjapip
, której używasz do instalacji,ray
nie jest tą samą, która jest aktualizowana. Możesz to sprawdzićpip --version
. Ponadto system Windows nie jest obecnie obsługiwany, więc jeśli używasz systemu Windows, prawdopodobnie jest to problem.CPython używa globalnej blokady interpretera, która sprawia, że programowanie równoległe jest nieco bardziej interesujące niż C ++
W tym temacie znajduje się kilka przydatnych przykładów i opisów wyzwania:
Obejście Python Global Interpreter Lock (GIL) w systemach wielordzeniowych przy użyciu zestawu zadań w systemie Linux?
źródło
Rozwiązaniem, jak powiedzieli inni, jest użycie wielu procesów. To, która struktura jest bardziej odpowiednia, zależy jednak od wielu czynników. Oprócz tych, o których już wspomniałem, jest też charm4py i mpi4py (jestem twórcą charm4py).
Istnieje bardziej wydajny sposób implementacji powyższego przykładu niż użycie abstrakcji puli procesów roboczych. Pętla główna wysyła te same parametry (w tym pełny wykres
G
) do pracowników w każdej z 1000 iteracji. Ponieważ co najmniej jeden pracownik będzie rezydował w innym procesie, wiąże się to z kopiowaniem i wysyłaniem argumentów do innych procesów. Może to być bardzo kosztowne w zależności od wielkości obiektów. Zamiast tego sensowne jest, aby pracownicy zapisywali stan i po prostu wysyłali zaktualizowane informacje.Na przykład w charm4py można to zrobić w następujący sposób:
Zauważ, że w tym przykładzie naprawdę potrzebujemy tylko jednego pracownika. Główna pętla mogłaby wykonać jedną z funkcji, a drugą kazać pracownikowi. Ale mój kod pomaga zilustrować kilka rzeczy:
result_a.get()
jest zablokowany czekając na wynik, pracownikowi robi obliczeń w tym samym procesie.źródło
W niektórych przypadkach możliwe jest automatyczne zrównoleglenie pętli za pomocą Numba , chociaż działa to tylko z niewielkim podzbiorem Pythona:
Niestety wydaje się, że Numba działa tylko z tablicami Numpy, ale nie z innymi obiektami Pythona. Teoretycznie może być również możliwe skompilowanie Pythona do C ++, a następnie automatyczne zrównoleglenie go za pomocą kompilatora Intel C ++ , chociaż jeszcze tego nie próbowałem.
źródło
joblib
Biblioteki można używać do wykonywania obliczeń równoległych i przetwarzania wieloprocesowego.Możesz po prostu utworzyć funkcję,
foo
którą chcesz uruchamiać równolegle i na podstawie następującego fragmentu kodu implementować przetwarzanie równoległe:Gdzie
num_cores
można uzyskać zmultiprocessing
biblioteki w następujący sposób:Jeśli masz funkcję z więcej niż jednym argumentem wejściowym i chcesz po prostu wykonać iterację po jednym z argumentów za pomocą listy, możesz użyć
partial
funkcji zfunctools
biblioteki w następujący sposób:Możesz znaleźć pełne wyjaśnienie wieloprocesorowości w Pythonie i R z kilkoma przykładami tutaj .
źródło