2016-03-03 50 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两个问题都可以。 –