Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pmap and thread count

Tags:

clojure

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?

like image 204
Sebastian Avatar asked Feb 22 '23 16:02

Sebastian


1 Answers

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:

  1. future uses a cached thread pool which has no size limit;

  2. 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.

like image 104
Michał Marczyk Avatar answered Mar 05 '23 06:03

Michał Marczyk