pmap : Parallel map
(require pmap) | package: pmap |
1 pmap
procedure
Proc : (procedure?) list : (list?)
The pmapfutures works as map but applies the function to every item in the list or lists in parallel using futures.
It’s restrictions is the same as for futures and map in general in Racket.
; ;Example: >(pmapf + '(1 2 3) '(1 2 3)) >'(2 4 6)
If the function applied is to simple pmapf might perform worse than map because of the overhead a future generate.
procedure
Proc : (quoted-lambda?) list : (list?)
The pmapplaces works almost as map and applies the function to every item in the list or lists in parallel using places. places has some restrictions and that impacts on the implementation in several ways, READ ON!
The first concern is that only some values, as determined by place-message-allowed? can be sent to another place. Unfortunately, a procedure cannot be sent. The current implementation of pmapp demands that the function sent is explicitly quoted.
Second, on creation of a place, a .rkt file is loaded into the new place, and one function defined within that file gets executed. The current implementation of pmapp loads a file, "pmapp_worker.rkt", which receives the quoted function, the arguments for an iteration, and evals the function with these arguments. This means that the bindings available are limited to those which are required by "pmapp_worker.rkt". For now, this includes racket, racket/fixnum and math. Since "pmapp_worker.rkt" is part of this package, it is not easy to change these without modifying the package. It should however be possible, within the body of the quoted function, to use dynamic-require.
As of v1.1 pmapp starts a maximum of one place per cpu-core or less if the number of jobs is smaller than the number of cpu-cores.
pmapp shows it strength in heavier calculations like approximating the Mandelbrot set, see the comparison section.
; ;Example_1: >(pmapp '(lambda (x y)(+ x y)) '(1 2 3) '(1 2 3)) >'(2 4 6) >(pmapp '(lambda (x y)(fl+ x y)) '(1.0 2.0 3.0) '(1.0 2.0 3.0)) >'(2.0 4.0 6.0)
A more natural way to use it:
; ;Example_2: >(define f '(lambda (x y)(+ x y))) >(pmapp f '(1 2 3) '(1 2 3)) >'(2 4 6)
procedure
Places : (exact-nonnegativ-integer?) Proc : (quoted-lambda?) list : (list?)
pmapp-max works as pmapp but with an aditional parameter setting the max number of places to use.
2 pmapp-c
pmapp-continuous is pmapp in parts. It works like pmapp but its set up for continuous work.
procedure
(pmapp-c-start Places) → list?
Places : (exact-nonnegativ-integer?)
pmapp-c-start starts a maximum of places given by the parameter. This is preferebly done in the beginning of the program as the places has a startup time.
procedure
Places : (list?) Proc : (quoted-lambda?) list : (list?)
Works as pmapp but with an additional parameter.
procedure
(pmapp-c-stop Places) → list?
Places : (list?)
Stops the places started by pmapp-c-start.
; ;Example: >(define pls (pmapp-c-start 2)) ; ;Start two places >(define f '(lambda (x y)(+ x y))) >(pmapp-c pls f '(1 2 3) '(1 2 3)) (code:coment ";Send and recive") >'(2 4 6) >(pmapp-c-stop pls); ;Stops two places >
3 Comparison
We compare here running the core of a Mandelbrot-set computation, using the code described in Parallelism with Futures , four times, with flonum:
; (mandelbrot 10000000 62 500 1000), four calculations "(12340.885 ms)"; map "(8113.297 ms)"; pmapf "(1727.656 ms)"; pmapp "(1526.297 ms)"; pmapp-m two places "(598.170 ms)"; pmapp-c four places
; (mandelbrot 100000 62 500 1000), four calculations "(149.705 ms)"; map "(96.563 ms)"; pmapf "(1588.309 ms)"; pmapp "(1290.812 ms)"; pmapp-m two places "(14.502 ms)"; pmapp-c four places
As seen above, the number of itterations has significant impact on the performance.
The computations where done with an old "Quad Core 2.4Ghz" CPU.