Wzorzec, z którym się zetknąłem już wiele razy, jest taki, w którym należy sprawdzić listę wartości, mapując na niej jakiś test i sprawdzając, czy którykolwiek lub wszystkie elementy przeszły. Typowym rozwiązaniem jest po prostu użycie wygodnych wbudowanych all
i any
.
Problem polega na tym, że oceniają one szeregowo. W wielu przypadkach ocena byłaby znacznie szybsza równolegle z zakończeniem procesu, gdy jakikolwiek wątek znajdzie „Fałsz” all
lub „Prawda” dla any
. Jestem całkiem pewien, że zachowanie zwarciowe nie może być zaimplementowane przy użyciu Control.Parallel, ponieważ wymaga komunikacji między procesami i nie rozumiem nigdzie wystarczająco blisko Control.Concurrent, aby to zaimplementować.
Jest to dość powszechny wzorzec w matematyce (np. Miller-Rabin Primality), więc wydaje mi się, że ktoś prawdopodobnie już wymyślił rozwiązanie tego problemu, ale z oczywistych powodów szuka w Google hasła „równoległe lub / i / dowolne / wszystkie na liście” haskell ”nie zwraca wielu trafnych wyników.
źródło
unamb
bibliotecepthreads
w C, czy zielonymi w Haskell). Nie uruchamiasz wielu serwerów w celu obsługi współbieżnych żądań sieciowych, zamiast tego uruchamiasz wiele wątków w jednym procesie! To samo dotyczy równoległości. Rozwijasz tyle wątków, ile posiadasz procesorów i dzielisz pracę równo, dbając w ten sposób o zadania związane z procesorem. Wypróbuj tę bibliotekę, aby się przekonać github.com/lehins/haskell-schedulerOdpowiedzi:
W wielu realistycznych programach można w tym celu stosować strategie równoległe. Wynika to z faktu, że chociaż nie ma jawnego mechanizmu anulowania niepotrzebnych obliczeń, nastąpi to niejawnie, gdy uruchomi się moduł czyszczenia pamięci. Jako konkretny przykład rozważ następujący program:
Wykorzystuje strategię listy równoległej do wyszukiwania
waldo = 0
(które nigdy nie zostaną znalezione) w danych wyjściowych 100 strumieni PRNG po 40 milionów liczb. Skompiluj i uruchom:i ustala cztery rdzenie przez około 16s, ostatecznie drukując
False
. Zwróć uwagę w statystykach, że wszystkie 100 iskier jest „konwertowanych” i dlatego biegną do końca:Teraz zmień
waldo
na wartość, którą można znaleźć wcześnie:i zmodyfikuj,
main
aby utrzymać wątek przy życiu przez 10 sekund:Zauważysz, że drukuje
True
prawie natychmiast, ale 4 rdzenie pozostają na 100% procesorze (przynajmniej przez krótką chwilę), co ilustruje, że niepotrzebne obliczenia nadal działają i nie są zwarte, tak jak się obawiałeś.ALE , rzeczy się zmieniają, jeśli wymusisz odśmiecanie po otrzymaniu odpowiedzi:
Teraz zobaczysz, że procesor przechodzi w stan bezczynności wkrótce po wydrukowaniu
True
, a statystyki pokazują, że większość obliczeń została wyrzucona przez śmieci przed uruchomieniem:W realistycznych programach wyraźne
performGC
nie będzie potrzebne, ponieważ GC będą przeprowadzane regularnie. Niektóre niepotrzebne obliczenia będą nadal działać po znalezieniu odpowiedzi, ale w wielu realistycznych scenariuszach część niepotrzebnych obliczeń nie będzie szczególnie ważnym czynnikiem.W szczególności, jeśli lista jest duża, a każdy pojedynczy test elementu listy jest szybki, strategie równoległe będą miały doskonałą wydajność w świecie rzeczywistym i będą łatwe do wdrożenia w okazjach.
źródło