首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >频繁GC防止火花并行运行

频繁GC防止火花并行运行
EN

Stack Overflow用户
提问于 2016-03-28 20:18:24
回答 1查看 252关注 0票数 13

我尝试在这里运行第一个示例:http://chimera.labs.oreilly.com/books/1230000000929/ch03.html

代码:https://github.com/simonmar/parconc-examples/blob/master/strat.hs

代码语言:javascript
复制
import Control.Parallel
import Control.Parallel.Strategies (rpar, Strategy, using)
import Text.Printf
import System.Environment

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

main = print pair
 where
  pair =
-- <<pair
   (fib 35, fib 36) `using` parPair
-- >>

-- <<parPair
parPair :: Strategy (a,b)
parPair (a,b) = do
  a' <- rpar a
  b' <- rpar b
  return (a',b')
-- >>

我使用ghc 7.10.2 (在OSX上,使用多核机器)使用以下命令进行构建:

代码语言:javascript
复制
ghc -O2 strat.hs -threaded -rtsopts -eventlog

并使用以下方法运行:

代码语言:javascript
复制
./strat +RTS -N2 -l -s

我预计两个fibs计算将并行运行(前面的章节示例按预期工作,因此没有设置问题),而且我完全没有得到任何加速,如下所示:

代码语言:javascript
复制
  % ./strat +RTS -N2 -l -s
(14930352,24157817)
   3,127,178,800 bytes allocated in the heap
       6,323,360 bytes copied during GC
          70,000 bytes maximum residency (2 sample(s))
          31,576 bytes maximum slop
               2 MB total memory in use (0 MB lost due to fragmentation)

                                     Tot time (elapsed)  Avg pause  Max pause
  Gen  0      5963 colls,  5963 par    0.179s   0.074s     0.0000s    0.0001s
  Gen  1         2 colls,     1 par    0.000s   0.000s     0.0001s    0.0001s

  Parallel GC work balance: 2.34% (serial 0%, perfect 100%)

  TASKS: 6 (1 bound, 5 peak workers (5 total), using -N2)

  SPARKS: 2 (0 converted, 0 overflowed, 0 dud, 1 GC'd, 1 fizzled)

  INIT    time    0.000s  (  0.001s elapsed)
  MUT     time    1.809s  (  1.870s elapsed)
  GC      time    0.180s  (  0.074s elapsed)
  EXIT    time    0.000s  (  0.000s elapsed)
  Total   time    1.991s  (  1.945s elapsed)

  Alloc rate    1,728,514,772 bytes per MUT second

  Productivity  91.0% of total user, 93.1% of total elapsed

gc_alloc_block_sync: 238
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0

-N1得到类似的结果(省略)。

GC集合的#看起来很可疑,就像#haskell初学者中的其他人指出的那样,所以我尝试在运行时添加-A16M。结果看上去更符合预期:

代码语言:javascript
复制
  % ./strat +RTS -N2 -l -s -A16M
(14930352,24157817)
   3,127,179,920 bytes allocated in the heap
         260,960 bytes copied during GC
          69,984 bytes maximum residency (2 sample(s))
          28,320 bytes maximum slop
              33 MB total memory in use (0 MB lost due to fragmentation)

                                     Tot time (elapsed)  Avg pause  Max pause
  Gen  0       115 colls,   115 par    0.105s   0.002s     0.0000s    0.0003s
  Gen  1         2 colls,     1 par    0.000s   0.000s     0.0002s    0.0002s

  Parallel GC work balance: 71.25% (serial 0%, perfect 100%)

  TASKS: 6 (1 bound, 5 peak workers (5 total), using -N2)

  SPARKS: 2 (1 converted, 0 overflowed, 0 dud, 0 GC'd, 1 fizzled)

  INIT    time    0.001s  (  0.001s elapsed)
  MUT     time    1.579s  (  1.087s elapsed)
  GC      time    0.106s  (  0.002s elapsed)
  EXIT    time    0.000s  (  0.000s elapsed)
  Total   time    1.686s  (  1.091s elapsed)

  Alloc rate    1,980,993,138 bytes per MUT second

  Productivity  93.7% of total user, 144.8% of total elapsed

gc_alloc_block_sync: 27
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0

问题是:为什么这是行为?即使有了频繁的GC,我仍然直觉地期望两个火花在其他90%的运行时间中并行运行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-10 14:44:55

是的,这实际上是GHC8.0.1和更早版本中的一个bug (我正在为8.0.2修复它)。问题是fib 35fib 36表达式是常量的,因此GHC将它们作为CAF提升到顶层,而RTS错误地假设CAF是不可访问的,因此垃圾收集火花。

您可以通过在命令行上传递参数使表达式非常量来解决这个问题:

代码语言:javascript
复制
main = do
     [a,b] <- map read <$> getArgs
     let pair = (fib a, fib b) `using` parPair
     print pair

然后使用./strat 35 36运行程序。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36270447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档