haskell中的平行映射

haskell中的平行映射,haskell,parallel-processing,multicore,combinators,Haskell,Parallel Processing,Multicore,Combinators,是否有map的替代品可以并行计算列表?我不需要懒惰 类似于:pmap::(a->b)->[a]->[b]让我pmap昂贵的功能大列表,让我的所有内核都达到100%。是的,请参阅: 将通过rdeepseq策略并行评估列表中的每个元素。请注意,如果您的元素太便宜,无法获得并行评估每个元素的好处,那么使用具有良好块值的parListChunk可能会提供更好的性能(因为它可以节省每个元素的火花) 编辑:基于你的问题,我觉得我应该解释为什么这是一个答案。那是因为哈斯克尔很懒!考虑语句 let bs = m

是否有
map
的替代品可以并行计算列表?我不需要懒惰

类似于:
pmap::(a->b)->[a]->[b]
让我
pmap昂贵的功能大列表
,让我的所有内核都达到100%。

是的,请参阅:

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

编辑:基于你的问题,我觉得我应该解释为什么这是一个答案。那是因为哈斯克尔很懒!考虑语句

let bs = map expensiveFunction as
没有进行任何评估。您刚刚创建了一个映射
expensiveFunction
的thunk。那么我们如何并行地评估它呢

let bs = map expensiveFunction as
    cs = bs `using` parList rdeepseq
现在不要在以后的计算中使用
bs
列表,而是使用
cs
列表。瞧,你不需要一个并行映射,你可以使用常规(惰性)映射和并行评估策略

编辑:如果你环顾四周,你会看到这个函数,它完成了我在这里展示的功能,但是被包装成了一个helper函数

作为对您评论的回应,下面的代码是否不适合您?它对我有用

import Control.Parallel.Strategies

func as =
        let bs = map (+1) as
            cs = bs `using` parList rdeepseq
        in cs

除了像Tom所描述的那样自己使用明确的策略外,该软件包:

其中策略参数类似于
rdeepseq

par monad包中还有
parMap
(您从纯Haskell中走出来,进入一个并行monad):


par monad包是。

我尝试使用'parList rdeepseq执行
pmap f x=(map f x)`但GHC抱怨rdeepseq需要一个参数。@clark看到我粘贴的代码-这应该加载到GHCi fine中。对你有用吗?表达式
parMap rdeepseq f as
应该做同样的事情。对我不起作用。“没有因使用'rdeepseq'@clark而产生的(Control.DeepSeq.NFData b)实例。您必须在特定上下文中使用它,或者使用显式类型签名。确保列表中的元素具有
NFData
实例-这是使用
rdeepseq
所必需的。如果这太繁重了,那么使用
rseq
,它将计算为whnf。@clark您是否使用threaded(
ghc-O2-threaded blah.hs--make
)编译并使用正确的RTS选项(
/blah+RTS-Nx
),其中
x
是您要使用的内核数,例如
2
?注意:在GHC 7上,您应该能够键入
GHC-O2-threaded-with-rtsopts=-N blah.hs
并运行
/blah
。这里有一个小警告。parMap使用的是严格的mapM。这意味着在开始计算之前,列表脊椎会被完全评估-如果列表很长,例如,您正在对从(巨大)文件读取的记录进行parMap'ping,这可能不是您想要的。也许这对于一个懒惰的parMap或者通过循环分发元素会更好。
import Control.Parallel.Strategies

func as =
        let bs = map (+1) as
            cs = bs `using` parList rdeepseq
        in cs
 parMap :: Strategy b -> (a -> b) -> [a] -> [b]
 parMap :: NFData b => (a -> b) -> [a] -> Par [b]