2010-01-20 48 views
28

使用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成語會起作用嗎?

+0

如果適用,不要忘記利用記憶。 http://richhickey.github.com/clojure/clojure.core-api.html#clojure。core/memoize – 2010-01-22 02:17:06

回答

19

這個問題:how-to-efficiently-apply-a-medium-weight-function-in-parallel在一個非常相似的情況下也解決了這個問題。

當前最好的答案是使用partition將它分成塊。然後將映射函數映射到每個塊上。然後重新組合結果。映射簡化風格。

+0

我真的想在每個塊上使用'pmap'嗎?我認爲這仍然會創造一個未來的每一件物品。 對於我來說,將每個卡盤上的「未來」映射出來會更有意義。 – 2010-01-20 21:26:34

+3

這個想法是增加塊大小,以便在仍然填充所有內核的同時節省協調開銷。並非所有數據集都有這樣的甜蜜點。 – 2010-01-21 00:35:24

+1

啊哈。我需要考慮一個額外的抽象層次。我在這個塊上使用了''pmap''函數,該函數會''將我的處理函數映射到塊的每個成員上。你是這個意思嗎? – 2010-01-21 13:42:13

0

您可以使用某種手工繪製的map/reduce。也看看swarmiji框架。

「分佈式計算系統,幫助編寫和運行Clojure的代碼並行 - 跨內核和處理器」

+1

swarmiji如果在Clojure中分佈式計算的庫。我印象中這個問題更多地集中在單系統並行實踐上。 – 2010-01-20 20:12:23

5

可悲的是,這還不是一個有效的答案,但未來需要注意的是Rich與Java 7中的fork/join庫一起工作。如果您在github上查看他的Par分支,他已經完成了一些工作,最後我看到了早期的回報是驚人的。

Rich試用它的例子。

http://paste.lisp.org/display/84027

+2

其實我已經發現現在可以用Java6,github的Clojure「par」分支和Rich Hickey提供的jsr166y.jar文件進行嘗試:http://cloud.github.com/downloads/richhickey/clojure/ jsr166y.jar – 2010-01-21 19:57:42

+0

哦,真的嗎?可能得看看,因爲Par看起來很棒。感謝您的提示,因爲我錯過了這一點。 – Runevault 2010-01-22 11:59:42

+3

粘貼死了 – 2013-03-21 15:41:30

2

叉/加入這一和類似線程早期的答案中提到的工作終於結出了果實爲reducers庫,這可能是值得一試。

相關問題