Tôi tình cờ gặp sự cố với Eval
đơn lẻ và rpar
Strategy
trong Haskell. Hãy xem xét đoạn mã sau:Làm thế nào để đánh giá tuple song song bằng cách sử dụng chiến lược rpar trong Haskell?
module Main where
import Control.Parallel.Strategies
main :: IO()
main = print . sum . inParallel2 $ [1..10000]
inParallel :: [Double] -> [Double]
inParallel xss = runEval . go $ xss
where
go [] = return []
go (x:xs) = do
x' <- rpar $ x + 1
xs' <- go xs
return (x':xs')
inParallel2 :: [Double] -> [Double]
inParallel2 xss = runEval . go $ xss
where
go [] = return []
go [x] = return $ [x + 1]
go (x:y:xs) = do
(x',y') <- rpar $ (x + 1, y + 1)
xs' <- go xs
return (x':y':xs'
tôi biên dịch và chạy nó như thế này:
ghc -O2 -Wall -threaded -rtsopts -fforce-recomp -eventlog eval.hs
./eval +RTS -N3 -ls -s
Khi tôi sử dụng inParallel
chức năng xử lý song song hoạt động như mong đợi. Trong thống kê thời gian chạy ra tôi thấy:
SPARKS: 100000 (100000 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
Khi tôi chuyển sang inParallel2
chức năng xử lý song song tất cả đã biến mất:
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
Tại sao không đánh giá các bộ làm việc tại song song? Tôi đã thử buộc bộ tuple trước khi chuyển nó tới rpar:
rpar $!! (x + 1, y + 1)
nhưng vẫn không có kết quả. Tôi đang làm gì sai?
Cảm ơn! Vấn đề này thực sự nảy sinh khi tôi đọc hướng dẫn của Marlow và thực hiện một số bài tập của riêng tôi. Thêm 1 chỉ là một ví dụ, tôi không muốn làm phức tạp mã mẫu với một số tính toán phức tạp. –