我正在尝试学习如何使用 Control.Parallel 模块,但我认为我没有做对。

我正在尝试运行以下代码 (fibs.hs)。

import Control.Parallel

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = p `par` (q `pseq`  (p + q))
    where
      p = fib (n-1)
      q = fib (n-2)


main = print $ fib 30

我编译了这个:
ghc -O2 --make -threaded fibs.hs

然后我在执行这个程序时得到以下结果(一个 Python 脚本的输出,该脚本运行每个程序 100 次并返回执行时间的平均值和标准偏差):
./fibs +RTS -N1 -> avg= 0.060203 s, deviation = 0.004112 s
./fibs +RTS -N2 -> avg= 0.052335 s, deviation = 0.006713 s
./fibs +RTS -N3 -> avg= 0.052935 s, deviation = 0.006183 s
./fibs +RTS -N4 -> avg= 0.053976 s, deviation = 0.007106 s
./fibs +RTS -N5 -> avg= 0.055227 s, deviation = 0.008598 s
./fibs +RTS -N6 -> avg= 0.055703 s, deviation = 0.006537 s
./fibs +RTS -N7 -> avg= 0.058327 s, deviation = 0.007526 s

我的问题是:
  • 当我评估时到底发生了什么:
    a `par` (b `pseq` (a + b))   ?
    

    我知道 par b 应该提示编译器关于与 b 并行计算 a 并返回 b。行。但是 pseq 有什么作用呢?
  • 为什么我看到这么小的性能提升?
    我在 Intel Core 2 Quad 机器上运行它。我希望使用 -N5 或 -N6 运行不会对性能产生真正的影响,或者该程序实际上会开始表现得很糟糕。但是为什么我看不到从 -N2 到 -N3 的改进,为什么初始改进如此之小?
  • 最佳答案

    作为 Don explained ,问题是你创造了太多的 Spark 。以下是您如何重写它以获得良好的加速。

    import Control.Parallel
    
    cutoff :: Int
    cutoff = 20
    
    parFib :: Int -> Int
    parFib n | n < cutoff = fib n
    parFib n = p `par` q `pseq` (p + q)
        where
          p = parFib $ n - 1
          q = parFib $ n - 2
    
    fib :: Int -> Int
    fib 0 = 0
    fib 1 = 1
    fib n = fib (n - 1) + fib (n - 2)
    
    main :: IO ()
    main = print $ parFib 40
    

    示范:
    [computer ~]$ ghc --make -threaded -O2 Main.hs
    [1 of 1] Compiling Main             ( Main.hs, Main.o )
    Linking Main ...
    [computer ~]$ time ./Main +RTS -N1
    102334155
    
    real    0m1.509s
    user    0m1.450s
    sys     0m0.003s
    [computer ~]$ time ./Main +RTS -N2
    102334155
    
    real    0m0.776s
    user    0m1.487s
    sys     0m0.023s
    [computer ~]$ time ./Main +RTS -N3
    102334155
    
    real    0m0.564s
    user    0m1.487s
    sys     0m0.030s
    [computer ~]$ time ./Main +RTS -N4
    102334155
    
    real    0m0.510s
    user    0m1.587s
    sys     0m0.047s
    [computer ~]$
    

    关于multithreading - Haskell 中的多核编程 - Control.Parallel,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1798996/

    10-13 05:58