From 6e2487bffaf40fa2c4ff9dc42a0462011304866a Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Wed, 31 Aug 2011 12:11:33 -0600 Subject: [PATCH] Guide text for places --- collects/scribblings/guide/performance.scrbl | 1 + collects/scribblings/guide/places.scrbl | 93 ++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 collects/scribblings/guide/places.scrbl diff --git a/collects/scribblings/guide/performance.scrbl b/collects/scribblings/guide/performance.scrbl index c52339611d..a1ff2a9a79 100644 --- a/collects/scribblings/guide/performance.scrbl +++ b/collects/scribblings/guide/performance.scrbl @@ -394,3 +394,4 @@ argument instead. @; ---------------------------------------------------------------------- @include-section["futures.scrbl"] +@include-section["places.scrbl"] diff --git a/collects/scribblings/guide/places.scrbl b/collects/scribblings/guide/places.scrbl new file mode 100644 index 0000000000..5d6dbce21e --- /dev/null +++ b/collects/scribblings/guide/places.scrbl @@ -0,0 +1,93 @@ +#lang scribble/doc +@(require scribble/manual "guide-utils.rkt" + (for-label racket/flonum racket/place)) + +@title[#:tag "effective-places"]{Parallelism with Places} + +The @racketmodname[racket/place] library provides support for +performance improvement through parallelism with the @racket[place] +form. Two places communicate using @racket[place-channel-put] and +@racket[place-channel-get] functions. Places contains the full +expressive power of the Racket language. However, the places design +restricts both the methods of inter-place communication and the type +of values permitted inside communication messages. + +The @racket[place] form spawns a new pristine racket execution +context, which the OS can schedule on any available processor. As a +starting example, the racket program below uses a place to determine +whether any number in the list has a double that is also in the list: + +@codeblock{ +#lang racket + +(provide main) + +(define (any-double? l) + (for/or ([i (in-list l)]) + (for/or ([i2 (in-list l)]) + (= i2 (* 2 i))))) + +(define (main) + (define p (place ch + (define l (place-channel-get ch)) + (define l-double? (any-double? l)) + (place-channel-put ch l-double?))) + + (place-channel-put p (list 1 2 4 8)) + (printf "Has double? ~a\n" (place-channel-get p)) + (place-wait p)) +} + +The first argument to the place form is an identifier, which the +@racket[place] form binds to an initial place-channel. The remaining +argument expressions form the body of the @racket[place] form. The +body expressions use the initial place-channel to communicate with the +place which spawned the new place. + +In the example above, the place form has a body of three expressions. +The first receives a list of numbers over the initial place-channel +(@racket[ch]) and binds the list to @racket[l]. The second body +expression calls any-double? on the list and binds the result to +@racket[l-double?]. The last body expression sends the +@racket[l-double?] result back to the invoking place over the +@racket[ch] place-channel. + +The macro that implements the @racket[place] form performs two actions with +subtle consequences. First, it lifts the place body to an anonymous +module-scope function. This has the consequence that any function +referred to by the place body must be defined at module-scope. Second, +the place form expands into a @racket[dynamic-place] call, which +@racket[dynamic-require]s the current module in a newly created place. +@margin-note{When using places inside DrRacket, the module containg +place code must be saved to a file before it will execute.} +As part of the @racket[dynamic-require] the current module body is +evaluated in the new place. The consequence of this second action is +that places forms must not be called at module-scope or indirectly by +functions which are invoked at module scope. Both of these errors are +demonstrated in the code bellow. Failing to follow this precaution +will result in an infinite spawning of places as each spawned place +evaluates the module body and spawns an additional place. + +@codeblock{ +#lang racket + +(provide main) + +; do not do this +(define p (place ch + (place-channel-get ch))) + +(define (indirect-place-invocation) + (define p2 (place ch + (place-channel-get ch)))) + + +; do not do this either +(indirect-place-invocation) +} + +The example above is executed by running @exec{racket -tm double.rkt} +from the command line. The @Flag{t} tells racket to load the +@tt{double.rkt} module. The @Flag{m} instructs racket to run the +@racket[main] module. +