robie Projekt Euler problemu 21 do prac domowych i mam ten list ze zrozumieniem:Dlaczego wyliczenia list Haskella nie są wykonywane równolegle?
amicableNumberSums = [ x+y | x<-[1..10000], y <-[1..10000], (amicable x y)]
To zajmuje bardzo dużo czasu, aby wykonać (zrozumiałe, gdyż testuje 10000^2 pary liczb) i patrząc na mój cpu użycie pokazuje, że używany jest tylko 1 rdzeń.
Ponieważ nie ma żadnych skutków ubocznych w zrozumieniu listy, nie ma niebezpieczeństwa dla wielu par liczb testowanych w tym samym czasie. Czy istnieje sposób, aby Haskell zrobił to automatycznie, czy nie, w jaki sposób mój kod mógł zostać zmodyfikowany, aby to zrobić?
(Edit) Błąd podczas uruchamiania drukowania (amicableNumberSums using
parList):
Couldn't match type `a0 -> Eval a0' with `[Int]'
Expected type: Strategy [Int]
Actual type: Strategy a0 -> Strategy [a0]
In the second argument of `using', namely `parList'
In the first argument of `print', namely
`(amicableNumberSums `using` parList)'
In the expression: print (amicableNumberSums `using` parList)
(Edit) Wydajność z dwóch proponowanych metod:
Ørjan Johansen's method: 218.79s elapsed parallel (4 cores + 4 hyperthreading)
279.37s elapsed sequential (single core)
bheklilr's method: 247.82s elapsed parallel (4 cores + 4 hyperthreading)
274.10s elapsed sequential (single core)
Original method: 278.69s elapsed
To nie jest tak duża prędkość jako Miałem nadzieję, ale teraz mam poprawną odpowiedź na problem i dopóki nie nauczyłem się więcej Haskella, to wystarczy.
Nie ma żadnych skutków ubocznych, ale zrozumienie listy wymaga, aby wyniki były w określonej kolejności, więc równoległość obliczeń nie jest taka trywialnie proste, jak możesz sobie wyobrazić. – amalloy