如何避免长时间运行的并行和并发Haskell计算中的性能下降

时间:2016-11-02 16:20:46

标签: multithreading haskell parallel-processing garbage-collection

我有一个AWS实例。我想运行一堆任务,一些内存和CPU密集。理想情况下,我想计算每项任务的时间信息。如果我连续运行它们,它会计算准确的计时信息,但速度很慢。如果我并行运行它们,整个事情就会更快,但是单个任务的速度会更慢,正如壁时间和线程CPU时间所报告的那样。

随着线程数量增加到CPU数量

,这种减速会增加

使用ghc-events-analyze+RTS -s进行的粗略检查表明,减速的来源(不出所料)GC暂停。使用RTS选项显示+RTS -qg -qb -qa -A256m(禁用并行GC,禁用负载平衡GC,禁用线程迁移以及增加GC分配区域)可以改善这一点,但不能完全消除它。

我正在使用forkIO运行线程,但除了打印进度信息之外,线程是独立且纯粹的。我使用parallel-io来管理正在运行的线程的数量,但是当我简单地尝试使用固定的线程池和任务队列的传统方法时,我仍然遇到了这个问题。

有关如何调试的任何建议吗?

编辑:

@jberryman问了一个例子。每个任务看起来都像下面的代码

computation params = do
  !x <- force params
  print $ "Starting computation on " ++ show params
  t1 <- getCPUTime
  !y <- fmap force $ do $
    ...some work with x ...
  t2 <- getCPUTime
  print $ "Finished computation on " ++ show params
  return (t2 - t1, y)

1 个答案:

答案 0 :(得分:3)

由于任务都是独立的,并且您在AWS实例(可能是Linux)上,因此使用forkProcess可能会获得更好的结果。这样,每个进程都有自己的GC池,当进程退出时,它将被释放,并且父进程不必担心为子进程保留多个进程ID并等待它们死掉。