pmap和线程数

时间:2012-01-30 14:12:41

标签: clojure

user=> (.. Runtime getRuntime availableProcessors)
2

评估此示例:http://clojuredocs.org/clojure_core/clojure.core/pmap#example_684我得到了

user=> (time (doall (map long-running-job (range 4)))) 
"Elapsed time: 12000.621 msecs"
(10 11 12 13)
user=> (time (doall (pmap long-running-job (range 5))))
"Elapsed time: 3000.454 msecs"
(10 11 12 13 14)
user=> (time (doall (pmap long-running-job (range 32))))
"Elapsed time: 3014.969 msecs"
(10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 3839 40 41)
user=> (time (doall (pmap long-running-job (range 33))))
"Elapsed time: 6001.526 msecs"
(10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42)

我想知道为什么我必须通过33等待33秒。为了结果。 pmap创建2(可用处理器)+ 2个线程,是吗?我认为当通过(范围5)时,它将在6秒内执行。为什么会有所不同?

1 个答案:

答案 0 :(得分:7)

实际上pmap不遵守“处理器+2”限制。这是常规mapfuture宏工作方式的结果:

  1. future使用没有大小限制的缓存线程池;

  2. map产生一个分块序列,即一次总是强制32个元素的序列,即使一个块的开头只有一小部分被调用者实际消耗了。

  3. 最终结果是pmap中的期货以32块为单位并行发布。

    请注意,这不违反pmap文档字符串中指定的合同。另一方面,代码可能导致人们相信“处理器+2”限制应该被尊重 - 就像map天真地写出来一样。实际上,pmap可能早于移动到chunked seqs,虽然我不确定,已经有一段时间了。