Ale*_*ard 29 parallel-processing clojure
使用clojure我在序列中有非常大量的数据,我想并行处理它,核心数量相对较少(4到8).
最简单的方法是使用pmap而不是将map处理函数映射到数据序列上.但协调开销导致我的案件净亏损.
我认为原因是pmap假设跨数据映射的函数非常昂贵.查看pmap的源代码,它似乎future依次为序列的每个元素构造一个,因此函数的每次调用都发生在一个单独的线程上(在可用内核的数量上循环).
以下是pmap的相关部分:
(defn pmap
"Like map, except f is applied in parallel. Semi-lazy in that the
parallel computation stays ahead of the consumption, but doesn't
realize the entire result unless required. Only useful for
computationally intensive functions where the time of f dominates
the coordination overhead."
([f coll]
(let [n (+ 2 (.. Runtime getRuntime availableProcessors))
rets (map #(future (f %)) coll)
step (fn step [[x & xs :as vs] fs]
(lazy-seq
(if-let [s (seq fs)]
(cons (deref x) (step xs (rest s)))
(map deref vs))))]
(step rets (drop n rets))))
;; multi-collection form of pmap elided
Run Code Online (Sandbox Code Playgroud)
在我的情况下,映射函数并不昂贵但序列很大(数百万条记录).我认为创建和解除引用许多未来的成本是平行增益在开销中丢失的地方.
我的理解是pmap正确的吗?
对于这种低成本但大规模重复处理而言,在clojure中是否有更好的模式pmap?我正在考虑以某种方式分块数据序列,然后在更大的块上运行线程.这是一个合理的方法,什么是clojure成语?
Art*_*ldt 20
这个问题:如何有效地应用中等权重并行功能也可以在非常类似的环境中解决这个问题.
目前最好的答案是用 partition它来分解成块.然后将map函数映射到每个块上.然后重新组合结果.映射简化风格.
可悲的是,还不是一个有效的答案,但是未来需要注意的是Rich在Java 7中使用fork/join库的工作.如果你在github上查看他的Par分支,他已经完成了一些工作,最后我看到了早期的回报令人惊叹.
Rich尝试它的例子.
http://paste.lisp.org/display/84027
| 归档时间: |
|
| 查看次数: |
8913 次 |
| 最近记录: |