[racket] parallelism

From: James Swaine (james.swaine at gmail.com)
Date: Fri May 13 09:32:46 EDT 2011

Hi Stephen,

I took the code you posted and tried filling in the bodies with my own code,
but wasn't able to crash DrRacket in the way you describe.  Could you
post/send me the actual code you were using?

Thanks,
James


On May 11, 2011, at 3:23 PM, Robby Findler wrote:

> You might try futures. Do read the guide first, of course.

I've tried some simple experiments.

The function in question iterates over every pixel of an image being
constructed:
       (for* ((y (in-range 0 height))
                 (x (in-range 0 width)))
            ; set the (x,y) pixel in the bitmap to be the result of a
function call on x and y
            )

I wrote another version that parallelizes the rows:
       (touch-all (for/list ((y (in-range 0 height)))
                                 (future (lambda () (for ((x (in-range
0 width)))

; set the (x,y) pixel as above
                                               ))))
       (define (touch-all futures)
               (for ((f futures)) (touch f)))
This version occasionally crashes DrRacket, but usually runs in about
twice the time of the non-futures version.

I wrote another version that parallelizes the columns:
       (for ((y (in-range 0 height)))
               (touch-all (for/list ((x (in-range 0 width)))
                                       (future (lambda ()
                                                       ; set the (x,y)
pixel as above
                                                       ))))))
I don't think I've ever gotten this version to run without crashing
DrRacket, so I have no timing data.

I wrote another version that parallelizes both rows and columns:
       (touch-all (for*/list ((y (in-range 0 height))
                                            (x (in-range 0 width)))
                               (future (lambda ()
                                               ; set the (x,y) pixel as
above
                                       ))))
This ran once without crashing, but it produced a wrong answer, and I
didn't get the timing data.  Every other time I've tried it, DrRacket
has crashed.

The likelihood of crashing seems to be lower if width and height are
smaller.




I then tried some simpler, smaller, non-image examples:

(define nums (build-list 1000 (lambda (x) x))

(time (touch-all (map (lambda (x) (future (lambda () (sqrt x)))) nums)))
vs.
(time (map sqrt nums))

I can't tell how much slower the former is than the latter, because
I've never gotten the latter to exceed 0 ms :-)
But at least the futures version has CPU time > real time, which
suggests there's some parallelization going on.





So I figured "maybe you're not supposed to use more futures than you
have processors."
I'm running on a machine with 4 parallel processors, according to
(processor-count).
So I tried something with only 3 futures:
(time (touch-all (map (lambda (x) (future (lambda () (map (lambda (y)
(* x y)) nums)))) '(1 2 3)))
as compared with a non-futures version
(time (map (lambda (x) (map (lambda (y) (* x y)) nums)) '(1 2 3)))
The futures version takes about twice as long as the non-futures
version.  But again, CPU time > real time, which suggests some
parallelization.


I suspect that futures would be more useful if each of the tasks were
bigger; I should try some more experiments with more complex tasks.

Stephen Bloch
sbloch at adelphi.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110513/2d39714a/attachment.html>

Posted on the users mailing list.