user=> (.. Runtime getRuntime availableProcessors)
2
And evaluating this example: http://clojuredocs.org/clojure_core/clojure.core/pmap#example_684 I get
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)
I wonder why I have to pass 33 to wait 33 sec. for result. pmap create 2 (available processors) + 2 threads, yes? I suppose that when pass (range 5) it will be executed in 6 sec. Why it is different?
Actually pmap
does not obey the "processors + 2" limit. That's a result of the ways in which the regular map
and the future
macro work:
future
uses a cached thread pool which has no size limit;
map
produces a chunked sequence, that is, one which is always forced 32 elements at a time, even if only a handful at the beginning of a chunk are actually consumed by the caller.
The ultimate result is that futures in pmap
are launched in parallel in blocks of 32.
Note that this is not in violation of the contract specified in pmap
's docstring. The code, on the other hand, might lead one to believe that it was intended that the "processors + 2" limit be respected -- as it would if map
was written naively. In fact, pmap
might well predate the move to chunked seqs, although I'm not really sure, it's been a while.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With