Często widzę użycie i wyjaśnienie równoległych strategii Haskell związanych z czystymi obliczeniami (na przykład fib
). Jednak nieczęsto go widzę w monadycznych konstrukcjach: czy istnieje rozsądna interpretacja wpływu par
i powiązanych funkcji po zastosowaniu do ST s
lub IO
? Czy przy takim użyciu można uzyskać jakiekolwiek przyspieszenie?Używanie równoległych strategii z monadami
Odpowiedz
Paralelizm w Monadzie IO jest bardziej poprawnie nazywany "Współbieżnością" i jest obsługiwany przez forkIO
i znajomych w module Control.Concurrent
.
Trudność z równoległością monady ST polega na tym, że ST jest koniecznie jednowątkowa - to jest jej cel. Istnieje leniwy wariant monady ST, Control.Monad.ST.Lazy
, który w zasadzie mógłby wspierać równoległą ocenę, ale nie jestem świadomy, że ktoś próbował to zrobić.
Istnieje nowa monada do równoległej oceny o nazwie Eval, którą można znaleźć w najnowszych wersjach parallel package. Polecam używanie monady Eval
z rpar
i rseq
zamiast obecnie par
i pseq
, ponieważ prowadzi to do bardziej niezawodnego i czytelnego kodu. Na przykład, zwykle fib
przykładem może być napisany
fib n = if n < 2 then 1 else
runEval $ do
x <- rpar (fib (n-1))
y <- rseq (fib (n-2))
return (x+y)
Istnieją pewne sytuacje, w których ma to sens, ale w ogóle nie powinno się robić. Przeanalizować następujące:
doPar =
let a = unsafePerformIO $ someIOCalc 1
b = unsafePerformIO $ someIOCalc 2
in a `par` b `pseq` a+b
w doPar
, obliczenia dla a
jest wywołała, po czym główny gwint ocenia b
. Ale możliwe jest, że po zakończeniu głównego wątku obliczenia b
, zacznie również oceniać a
. Teraz masz dwie wątki oceniające a
, co oznacza, że niektóre z operacji IO zostaną wykonane dwukrotnie (lub prawdopodobnie więcej). Ale jeśli jeden wątek zakończy ocenianie a
, drugi po prostu upuści to, co zostało zrobione do tej pory. Aby było to bezpieczne, potrzebujesz kilku rzeczy:
- Jest bezpieczny dla działań IO wykonywanych wiele razy.
- Bezpieczne jest wykonywanie tylko niektórych operacji we/wy (np. Nie ma czyszczenia).
- Akcje IO są wolne od jakichkolwiek warunków wyścigu. Jeśli jeden wątek mutuje niektóre dane podczas oceniania
a
, czy inny wątek działa również w sposób rozsądny? Prawdopodobnie nie. - Wszelkie rozmowy zagraniczne są ponownie uczestnik (trzeba to dla współbieżności w ogóle oczywiście)
Jeśli someIOCalc
wygląda to
someIOCalc n = do
prelaunchMissiles
threadDelay n
launchMissiles
to absolutnie nie jest bezpieczne w użyciu to z par
i unsafePerformIO
.
Czy kiedykolwiek warto? Może. Iskry są tanie, nawet tańsze niż nici, więc teoretycznie powinno to być zwiększenie wydajności. W praktyce być może nie tak bardzo. Roman Leschinsky ma miłe blog post about this.
Osobiście uważam, że o wiele łatwiej jest wnioskować o forkIO
.
- 1. Jak korzystać z równoległych strategii w Haskell
- 2. Spowolnienie podczas korzystania z równoległych strategii w Haskell
- 3. Używanie fabryki ze wzorem strategii
- 4. Używanie source() w równoległych pętlach foreach
- 5. Profilowanie wydajności wielowątkowej w programie Haskell - brak przyspieszeń z użyciem strategii równoległych
- 6. Jak używać strzałek Kleisli z monadami?
- 7. Pętle nad Monadami w Haskell
- 8. Rozpoczęcie równoległych transakcji równoległych w teście integracji
- 9. brak równoległych wątków z openMP
- 10. Skrypty powłoki: Używanie xargs do wykonywania równoległych instancji funkcji powłoki
- 11. Dlaczego wzorzec strategii jest nazywany wzorem strategii?
- 12. Różnica między wolnymi monadami a fixpointami funktorów?
- 13. Gdzie jest korzyść z używania wzorca strategii?
- 14. Strategiczny wzór - wybór strategii z licznikami
- 15. Parametryzowany wzór strategii
- 16. Jak zmienić liczbę równoległych procesów?
- 17. wielowątkowość (openMP) - liczba równoległych wątków
- 18. Macierz interakcji równoległych w R
- 19. MongoDB równoległych zapytań przez nodejs
- 20. Zalety/wady strategii Redis paginacji
- 21. Różne parametry w wzorcu strategii
- 22. Używanie jednego interfejsu Kinect dla systemu Windows dla dwóch równoległych procesów
- 23. Jak uzyskiwać z zadań równoległych w .NET 4.5
- 24. Jaki byłby lepszy sposób korzystania z biblioteki zadań równoległych
- 25. Biblioteka zadań równoległych z .net 4.0 a MPI.NET
- 26. Jaki jest preferowany sposób korzystania z kolekcji równoległych w Scali?
- 27. Wieloprocesorowe przetwarzanie w Pythonie dla procesów równoległych
- 28. Java około 100 równoległych wątków, zarządzanie pamięcią
- 29. Drukowanie na stdout w procesach równoległych IPython
- 30. granice Pythona w przetwarzaniu plików równoległych
Chcesz, aby twoje operacje we/wy były wykonywane w określonej kolejności (np. Najpierw otwórz plik, zamiast go przeczytać, a następnie go zamknij). Co chcesz tam zrównoleglić? – helium
@helum: wydaje się, że w większości przypadków pojawiają się zmienne dane lub podczas korzystania z FFI. –
Zastanawiam się nad tym. Często otwieram kilka dużych plików (100 megs) i rozpakowuję je w równoległych wątkach, a następnie pracuję z nimi po ich otwarciu. Są na tyle duże, że widać dobrą poprawę wydajności, ale wystarczająco małe, że mogę przechowywać je w pamięci. Zastanawiałem się, jak to zrobić w Haskel. –