使用clojure我有一個序列中的數據量非常大,我想並行處理它,並且核心數量相對較少(4到8)。更好地替代Clojure中的pmap,用於在大數據上並行處理中等廉價的功能?
最簡單的事情是不是map
使用pmap
,超過數據的序列映射我的處理功能。 但在我的案例的協調開銷導致淨虧損。
我認爲原因是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
在我的情況下,映射函數是不貴,但順序是巨大的(數百萬條記錄)。我認爲創造和取消引用很多期貨的成本是平行收益在開銷中損失的部分。
我的理解是pmap
是否正確?
clojure有沒有比pmap
這種成本較低但大規模重複處理更好的模式?我正在考慮以某種方式分割數據序列,然後在較大的塊上運行線程。 這是一個合理的方法,clojure成語會起作用嗎?
如果適用,不要忘記利用記憶。 http://richhickey.github.com/clojure/clojure.core-api.html#clojure。core/memoize – 2010-01-22 02:17:06