<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hi,<div><br></div><div>I am looking at parallelising some numerical computation with Racket. I’ve tried <font face="Courier">future/touch</font> first. However, the data for computation is passed as vectors and in my experiments with future/touch it would always find "synchronisation task” upon which all multicore-threads collapse into one core serialised computation.</div><div><br></div><div>Now, I decided to try <font face="Courier">place</font>. My idea is to make it similar to Common Lisp’s LPARALLEL: create workers <= number of cores and distribute tasks into those workers. The problem I have encountered, however, is that <font face="Courier">place-channel-get</font> seems to take forever to compute. Here is an example of some simulated computation on a vector using two places and trying to run them in parallel:</div><div><br></div><div><div><font face="Courier">#lang racket</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">(require racket/place)</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">(provide test-places1 test-places2 long-computation v1 v2 random-vector)</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">;;; Utilities: </font></div><div><font face="Courier">(define (random-list n)</font></div><div><font face="Courier">  (let loop ((i n) (r '()))</font></div><div><font face="Courier">    (if (zero? i)</font></div><div><font face="Courier">        r</font></div><div><font face="Courier">        (loop (sub1 i) (cons (random) r)))))</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">(define (random-vector n)</font></div><div><font face="Courier">  (let ((l (random-list n)))</font></div><div><font face="Courier">    (list->vector l)))</font></div><div><font face="Courier">  </font></div><div><font face="Courier">(define (vector-reduce f init v)</font></div><div><font face="Courier">  (let ((n (vector-length v)))</font></div><div><font face="Courier">    (let loop ((i 0) (r init))</font></div><div><font face="Courier">      (if (= i n)</font></div><div><font face="Courier">          r</font></div><div><font face="Courier">          (loop (add1 i) (f r (vector-ref v i)))))))</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">;;; This is  computation to be run in each place:</font></div><div><font face="Courier">(define (long-computation v)</font></div><div><font face="Courier">  (let ((n (vector-length v))</font></div><div><font face="Courier">        (v1 (vector-copy v)))  ; v is immutable, if want to mutate, must copy it</font></div><div><font face="Courier">    (let loop ((i 0))</font></div><div><font face="Courier">      (if (= i n)</font></div><div><font face="Courier">          (begin</font></div><div><font face="Courier">            (sleep 2)         ; make it work for a bit longer</font></div><div><font face="Courier">            (vector-reduce + 0.0 v1)) ; to make result printable</font></div><div><font face="Courier">          (begin</font></div><div><font face="Courier">            (vector-set! v1 i (* (exp (- (vector-ref v1 i)))</font></div><div><font face="Courier">                                 (sin (* pi (vector-ref v1 i)))))   ;flonum computation</font></div><div><font face="Courier">            (loop (add1 i)))))))</font></div><div><font face="Courier">      </font></div><div><font face="Courier">;;; two vectors to be sent to long-computation</font></div><div><font face="Courier">(define v1 (random-vector 100000))</font></div><div><font face="Courier">(define v2 (random-vector 100000))</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">;;; Test using one place:</font></div><div><font face="Courier">(define (test-places1)</font></div><div><font face="Courier">  (define p1</font></div><div><font face="Courier">    (place ch1</font></div><div><font face="Courier">           (define v (place-channel-get ch1))</font></div><div><font face="Courier">           (define w (long-computation v))</font></div><div><font face="Courier">           (place-channel-put ch1 w)))  </font></div><div><font face="Courier">  (place-channel-put p1 v1)</font></div><div><font face="Courier">  (time (place-channel-get p1)))</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">;;; Test using 2 places:</font></div><div><font face="Courier">(define (test-places2)</font></div><div><font face="Courier">  (define p1</font></div><div><font face="Courier">    (place ch1</font></div><div><font face="Courier">           (define v (place-channel-get ch1))</font></div><div><font face="Courier">           (define w (long-computation v))</font></div><div><font face="Courier">           (place-channel-put ch1 w)))</font></div><div><font face="Courier">  (define p2</font></div><div><font face="Courier">    (place ch2</font></div><div><font face="Courier">           (define v (place-channel-get ch2))</font></div><div><font face="Courier">           (define w (long-computation v))</font></div><div><font face="Courier">           (place-channel-put ch2 w)))</font></div><div><font face="Courier">  (place-channel-put p1 v1)</font></div><div><font face="Courier">  (place-channel-put p2 v2)</font></div><div><font face="Courier">  (sleep 2) ; hypothetically, after this results shoud be ready immidiately!</font></div><div><font face="Courier">  (time (list (place-channel-get p1) (place-channel-get p2))))</font></div><div><br></div></div><div>Exectution from <font face="Courier">racket</font> on MacBook Pro with Intel Core 2 Duo:</div><div><br></div><div><div><font face="Courier">-> (time (long-computation v1))</font></div><div><font face="Courier">cpu time: 42 real time: 2043 gc time: 0</font></div><div><font face="Courier">39523.12275516648</font></div></div><div><div><font face="Courier">-> (test-places1)</font></div><div><font face="Courier">cpu time: 7593 real time: 7475 gc time: 7001</font></div><div><font face="Courier">39523.12275516648</font></div><div><font face="Courier">-> (test-places2)</font></div><div><font face="Courier">cpu time: 16591 real time: 12492 gc time: 15485</font></div><div><font face="Courier">'(39523.12275516648 39505.415738171105)</font></div></div><div><br></div><div>So, the time of execution of <font face="Courier">(long-computation v1)</font> and the time of getting the result out of the channel in <font face="Courier">(test-places1)</font> should be more or less the same, but it is not. Furthermore, <font face="Courier">(test-places2)</font> takes almost twice as <font face="Courier">(test-places1)</font> (note, I put <font face="Courier">(time …)</font> around just getting the value, so it does not include the time of creating the place).</div><div><br></div><div>Am I doing something wrong?</div><div><br></div><div>Cheers, Alexey</div><div><br></div><div><br></div></body></html>