我希望将一个适度昂贵的函数映射到一个大型的懒惰seq并行。 pmap
很棒,但我对上下文切换很不满意。我想我需要增加传递给每个线程的工作块的大小。
我写了一个函数来将seq分解为块并将函数pmap到每个块上并重新组合它们。这“有效”,但结果并不壮观。原始代码基本上如下所示:
(pmap eval-polynomial (range x) coificients)
如何在保持懒惰的同时真正挤压它?
答案 0 :(得分:6)
如何使用partition
功能分解range
序列?在http://www.fatvat.co.uk/2009/05/jvisualvm-and-clojure.html
答案 1 :(得分:3)
我从http://www.braveclojure.com/zombie-metaphysics/查看ppmap函数。它允许您在指定块大小时进行pmap。
解决这个问题的方法是增加粒度,或者 每个并行化任务完成的工作量。在这种情况下,任务 是将映射函数应用于集合的一个元素。 粒度不是以任何标准单位来衡量的,但你要说的是 默认情况下,pmap的粒度为1。将粒度增加到两个 意味着你将映射函数应用于两个元素 而不是一个,所以任务所在的线程正在做更多的工作。 [...]只是为了好玩,我们可以将这项技术概括为一个功能 称为ppmap,用于分区pmap。它可以收到多个 集合,就像地图:
(defn ppmap
"Partitioned pmap, for grouping map ops together to make parallel
overhead worthwhile"
[grain-size f & colls]
(apply concat
(apply pmap
(fn [& pgroups] (doall (apply map f pgroups)))
(map (partial partition-all grain-size) colls))))
(time (dorun (ppmap 1000 clojure.string/lower-case orc-name-abbrevs)))
; => "Elapsed time: 44.902 msecs"
答案 2 :(得分:1)
如果你不介意一些有点异国情调的东西(以换取一些非常明显的加速),你可能还想看一下Penumbra-library的作者所做的工作,它提供了easy access to the GPU。< / p>
答案 3 :(得分:0)