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]