写“fib”并行运行:

我正在学习Haskell并尝试并行执行写代码,但Haskell总是按顺序运行它。 当我使用-N2运行时标志执行时,执行所需的时间比省略此标志要多。

这是代码:

import Control.Parallel
import Control.Parallel.Strategies

fib :: Int -> Int
fib 1 = 1
fib 0 = 1
fib n = fib (n - 1) + fib (n - 2)

fib2 :: Int -> Int
fib2 n = a `par` (b `pseq` (a+b))
    where a = fib n
          b = fib n + 1

fib3 :: Int -> Int
fib3 n = runEval $ do
                a <- rpar (fib n)
                b <- rpar (fib n + 1)
                rseq a
                rseq b
                return (a+b)

main = do putStrLn (show (fib3 40))

我做错了什么? 我在Intel Core i5的Windows 7以及Atom的Linux上尝试了这个示例。

这是来自我的控制台会话的日志:

ghc -rtsopts -threaded -O2 test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )

test +RTS -s
331160283
          64,496 bytes allocated in the heap
           2,024 bytes copied during GC
          42,888 bytes maximum residency (1 sample(s))
          22,648 bytes maximum slop
               1 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0:     0 collections,     0 parallel,  0.00s,  0.00s elapsed
  Generation 1:     1 collections,     0 parallel,  0.00s,  0.00s elapsed

  Parallel GC work balance: nan (0 / 0, ideal 1)

                        MUT time (elapsed)       GC time  (elapsed)
  Task  0 (worker) :    0.00s    (  6.59s)       0.00s    (  0.00s)
  Task  1 (worker) :    0.00s    (  0.00s)       0.00s    (  0.00s)
  Task  2 (bound)  :    6.33s    (  6.59s)       0.00s    (  0.00s)

  SPARKS: 2 (0 converted, 0 pruned)

  INIT  time    0.00s  (  0.00s elapsed)
  MUT   time    6.33s  (  6.59s elapsed)
  GC    time    0.00s  (  0.00s elapsed)
  EXIT  time    0.00s  (  0.00s elapsed)
  Total time    6.33s  (  6.59s elapsed)

  %GC time       0.0%  (0.0% elapsed)

  Alloc rate    10,191 bytes per MUT second

  Productivity 100.0% of total user, 96.0% of total elapsed

gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync_large_objects: 0
gen[1].sync_large_objects: 0


test +RTS -N2 -s 
331160283
          72,688 bytes allocated in the heap
           5,644 bytes copied during GC
          28,300 bytes maximum residency (1 sample(s))
          24,948 bytes maximum slop
               2 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0:     1 collections,     0 parallel,  0.00s,  0.00s elapsed
  Generation 1:     1 collections,     1 parallel,  0.00s,  0.01s elapsed

  Parallel GC work balance: 1.51 (937 / 621, ideal 2)

                        MUT time (elapsed)       GC time  (elapsed)
  Task  0 (worker) :    0.00s    (  9.29s)       0.00s    (  0.00s)
  Task  1 (worker) :    4.53s    (  9.29s)       0.00s    (  0.00s)
  Task  2 (bound)  :    5.84s    (  9.29s)       0.00s    (  0.01s)
  Task  3 (worker) :    0.00s    (  9.29s)       0.00s    (  0.00s)

  SPARKS: 2 (1 converted, 0 pruned)

  INIT  time    0.00s  (  0.00s elapsed)
  MUT   time   10.38s  (  9.29s elapsed)
  GC    time    0.00s  (  0.01s elapsed)
  EXIT  time    0.00s  (  0.00s elapsed)
  Total time   10.38s  (  9.30s elapsed)

  %GC time       0.0%  (0.1% elapsed)

  Alloc rate    7,006 bytes per MUT second

  Productivity 100.0% of total user, 111.6% of total elapsed

gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync_large_objects: 0
gen[1].sync_large_objects: 0

我认为答案是:“GHC将优化fib函数,使其不进行分配,并且没有分配的计算会给RTS带来问题,因为调度程序永远不会运行并进行负载平衡(这对于并行性是必需的)”正如西蒙在这个讨论小组中写道的 另外我找到了很好的教程。

链接地址: http://www.djcxy.com/p/57263.html

上一篇: Writing "fib" to run in parallel:

下一篇: How to test headers with rspec and rack