Добрый день.Данный код
import Control.DeepSeq
import Control.Exception
import Control.Parallel
import Control.Parallel.Strategies
import System.Environment
import Text.Printf
l = [34,56,43,1234,456,765,345,4574,58,878,978,456,34,234,1234123,1234,12341234]
f x = Just (sum [1..x])
fun1 :: [Maybe Integer]
fun1 = map f l `using` parList rdeepseq
fun2 :: [Maybe Integer]
fun2 = map f l `using` evalList (rparWith rdeepseq)
fun3 :: [Maybe Integer]
fun3 = map f l `using` evalList (rpar . force)
main :: IO ()
main = print fun1
Почему fun1
и fun2
работают последовательно?Из того, что я понял, rparWith должен зажечь свой аргумент.Ответ здесь утверждает то же самое.Но для fun1 и fun2 я получаю вывод типа «SPARKS: 0 (0 конвертировано, 0 переполнено, 0 dud, 0 GC'd, 0 fizzled)».Так что Искры даже не были созданы.fun3
работает как положено с созданием искр.Ты за помощь
UPD: И я обнаружил, что rdeepseq
делает пример из книги (параллельное и параллельное программирование в Haskell) работает последовательно.Книга говорит:
И мы можем использовать parPair для написания Стратегии, которая полностью оценивает оба компонента пары параллельно:
parPair rdeepseq rdeepseq :: (NFData a, NFData b)=> Стратегия (a, b)
Чтобы разбить, что происходит, когда эта Стратегия применяется к паре: parPair вызывает, а evalPair вызывает rparWith rdeepseq для каждого компонента пары.Таким образом, эффект состоит в том, что каждый компонент будет полностью оценен в нормальной форме параллельно.
Но если я запусту
(Just (fib 35), Just (fib 36)) `using` parPair rdeepseq rdeepseq
или даже
(fib 35, fib 36) `using` parPair rdeepseq rdeepseq
В Threadscope отображается только одно работающее ядро и создано 0 искр.
fib реализован следующим образом (из книги)
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)