2016-03-03 115 views
3

我下面的代碼:如何充分利用所有的CPU核心Clojure中

(defn compile-report [id] 
    (let [a (gen-first-part id) 
      b (gen-second-part id) 
      c (gen-third-part id) 
      d (gen-fourth-part id)] 

    (conj a b c d))) 

每「GEN-X-部分」功能是CPU密集型。據我瞭解,let表單將在單個線程上串行運行這些計算。如果我有一臺核心機器,那麼在它們自己的線程上運行每個核心機器都沒有意義,因爲它們都是cpu綁定的。不過,我有一臺4核心機器。我怎樣才能利用這些核心中的每一個,並將這些功能分配到它自己的核心?謝謝。

+0

核心異步也可以使用您的機器的所有核心,而不會阻塞。 –

+0

@ChrisMurphy - 它是如何做到的?每個線程只能按順序處理代碼,並且如果遇到(例如)I/O綁定函數,那麼該線程肯定會阻塞,直到函數返回。 – Zuriar

+0

每個go block都會嘗試使用一個單獨的線程,並且他們都將同時進行。隨着風扇飛速旋轉,您可以輕鬆讓您的多核計算機「最大化」(使用100%的可能處理週期)。 –

回答

10

你可以用你的CPU密集型功能爲future S:

(defn compile-report [id] 
    (let [a (future (gen-first-part id)) 
     b (future (gen-second-part id)) 
     c (future (gen-third-part id)) 
     d (future (gen-fourth-part id))] 

    (conj @a @b @c @d))) 

這會讓他們在單獨的線程中運行。 @a意味着(deref a)它將阻塞,直到結果可用。

如果你的函數處理更大的Clojure數據集,你也可以看看pmap

+0

謝謝,所以我猜測JVM/OS會很聰明,以實現它具有多核並相應地調度線程?另外,最後的連接形式在主線程中運行,所以整個線程阻塞直到所有的期貨都返回? – Zuriar

+3

@ user3231690兩個問題都可以。 –