Tôi có một chức năng Haskell tôi muốn đánh giá với kết quả trung gian chính xác:parBuffer đánh giá không cho tăng tốc dự kiến
f 0 x = 0
f n x = let tmp = f (n-1) x in
tmp + (x-tmp^2)/2
Do (^ 2) mức độ phức tạp tăng lên theo cấp số nhân trong n. Vì tôi muốn làm một âm mưu và các tính toán cho hai x khác nhau là hoàn toàn độc lập, tôi đã có thể mong đợi gần như tối ưu tốc độ từ đánh giá song song. Mã của tôi cho điều này:
import Data.Ratio
import Control.Parallel.Strategies
f 0 x = 0
f n x = let tmp = f (n-1) x in
tmp + (x-tmp^2)/2
main = do
it <- readLn
let fn = fromRational . f it
values = map fn [0,1%2..10] :: [Double]
computed = values `using` parBuffer 16 rseq
mapM_ (putStrLn . show) computed
Nhưng tôi ngạc nhiên điều này không thực sự mở rộng (trên i3 lõi kép của tôi với HT):
$ ghc -threaded -O f.hs
[1 of 1] Compiling Main (f.hs, f.o)
Linking f ...
$ time echo 20 | (./f +RTS -N1 > /dev/null)
real 0m4.760s
user 0m4.736s
sys 0m0.016s
$ time echo 20 | (./f +RTS -N2 > /dev/null)
real 0m4.041s
user 0m5.416s
sys 0m2.548s
$ time echo 20 | (./f +RTS -N3 > /dev/null)
real 0m4.884s
user 0m10.936s
sys 0m3.464s
$ time echo 20 | (./f +RTS -N4 > /dev/null)
real 0m5.536s
user 0m17.028s
sys 0m3.888s
Tôi đang làm gì sai ở đây? Có vẻ như nó dành khá nhiều thời gian trong khóa (sys?) Thay vì làm công việc hữu ích.
Có vẻ như bạn cần 'parList' rồi' parBuffer' – Ankur