Haskell/GHC中的驯服并行性



haskell newbie询问的有关使并行性有效工作的问题。

代码第14天的挑战的出现涉及创建一系列整数的MD5哈希,寻找可以满足某些属性的哈希的第一个N整数。我从本质上是通过创建哈希然后过滤它们来做到这一点。

我认为与并行性尝试这是一件好事,使用多个核心生成哈希。

哈希创建的非平行版本如下:

md5sequenceS :: [String]
md5sequenceS = [makeMd5 i | i <- [0..]]
    where makeMd5 i = stretch $ getHash (salt ++ show i)
          stretch h0 = foldr (_ h -> getHash h) h0 [1..2016]

...而且效果很好,尽管缓慢,在大约四分钟内给出答案。

并行版本如下:

md5sequenceS :: [String]
md5sequenceS = parMap rdeepseq (makeMd5) [0..]
    where makeMd5 i = stretch $ getHash (salt ++ show i)
          stretch h0 = foldr (_ h -> getHash h) h0 [1..2016]

...与parMap rdeepseq位相同。这不正常:它消耗了我的计算机上的所有可用内存,并且在隔离时间30分钟后仍无法产生答案。但是,它确实完全使用了所有处理器。

我该怎么做才能驯服这个失控的并行性?

(问题规格没有任何线索,我需要生成多少个哈希,但事实证明我需要大约30,000个整数。)

编辑以包括接受的答案

parBuffer策略可以用作

md5sequenceS = withStrategy (parBuffer 100 rdeepseq) $ map (makeMd5) [0..]
    where makeMd5 i = stretch $ getHash (salt ++ show i)
          stretch h0 = foldr (_ h -> getHash h) h0 [1..2016]

与单线程版本相比,性能不是很好,但这是另一个问题...

parMap将强制对所有列表的评估,在您的情况下是无限的。

而不是使用parMap,您可以考虑使用其他策略(例如parBuffer),该策略能够处理无限列表。

相关内容

  • 没有找到相关文章

最新更新