【问题标题】:Parallel map in haskellhaskell中的并行映射
【发布时间】:2011-08-02 03:30:49
【问题描述】:

是否有一些 map 的替代品可以并行评估列表?我不需要它偷懒。

类似:pmap :: (a -> b) -> [a] -> [b] 让我 pmap expensive_function big_list 并让我所有的核心都达到 100%。

【问题讨论】:

    标签: haskell parallel-processing multicore combinators


    【解决方案1】:

    除了像 Tom 所描述的那样自己使用显式策略之外,parallelalso exports parMap

     parMap :: Strategy b -> (a -> b) -> [a] -> [b]
    

    策略参数类似于rdeepseq

    par-monad 包中还有 parMap(你走出纯 Haskell,进入并行 monad):

     parMap :: NFData b => (a -> b) -> [a] -> Par [b]
    

    par-monad 包是documented here

    【讨论】:

    • 这里有一个小警告。 parMap 使用的是严格的 mapM。这意味着列表脊椎在计算开始之前被完全评估 - 如果列表很长,例如您正在对从(巨大)文件中读取的记录进行 parMap'ping,这可能不是您想要的。也许这对惰性 parMap 或通过循环分发元素会更好。
    【解决方案2】:

    是的,见parallel package

    ls `using` parList rdeepseq
    

    将通过rdeepseq 策略并行评估列表中的每个元素。请注意,如果您的元素太便宜而无法获得并行评估每个元素的好处(因为它可以节省每个元素的火花),则使用具有良好块值的 parListChunk 可能会提供更好的性能。

    编辑:根据您的问题,我觉得我应该解释为什么这是一个答案。这是因为 Haskell 很懒!考虑声明

    let bs = map expensiveFunction as
    

    没有进行任何评估。您刚刚创建了一个映射 expensiveFunction 的 thunk。那么我们如何并行评估呢?

    let bs = map expensiveFunction as
        cs = bs `using` parList rdeepseq
    

    现在不要在以后的计算中使用bs 列表,而是使用cs 列表。 IOW,您不需要并行映射,您可以使用常规(惰性)映射和并行评估策略。

    编辑:如果您环顾四周,您会看到 parMap 函数,它执行我在此处显示的操作,但封装在一个辅助函数中。

    针对您的评论,以下代码对您不起作用吗?它对我有用。

    import Control.Parallel.Strategies
    
    func as =
            let bs = map (+1) as
                cs = bs `using` parList rdeepseq
            in cs
    

    【讨论】:

    • 我试过 pmap f x = (map f x) `using` parList rdeepseq,但 GHC 抱怨 rdeepseq 需要一个参数。
    • @clark 查看我粘贴的代码 - 这应该可以很好地加载到 GHCi 中。对你起作用吗?表达式parMap rdeepseq f as 应该做同样的事情。
    • 对我不起作用。 “没有因使用 `rdeepseq' 而导致 (Control.DeepSeq.NFData b) 的实例”
    • @clark 您必须在特定上下文中使用它或使用显式类型签名。确保列表中的元素具有NFData 实例——这是使用rdeepseq 所必需的。如果这太繁琐,那么请改用rseq,它会评估为 whnf。
    • @clark 您是否使用线程 (ghc -O2 -threaded blah.hs --make) 进行编译并使用正确的 RTS 选项 (./blah +RTS -Nx) 其中 x 是您要使用的内核数,例如 2 ?请注意,在 GHC 7 上,您应该只能输入 ghc -O2 -threaded -with-rtsopts=-N blah.hs 并运行 ./blah
    猜你喜欢
    • 2012-07-24
    • 1970-01-01
    • 2013-04-04
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多