Revise places docs to fit the reference-manual style

This commit is contained in:
Matthew Flatt 2010-11-27 18:34:33 -07:00
parent af318c4501
commit 5c89df2f7f
3 changed files with 100 additions and 90 deletions

View File

@ -1,7 +1,7 @@
#lang scribble/doc #lang scribble/doc
@(require "mz.ss") @(require "mz.ss")
@title[#:tag "concurrency" #:style 'toc]{Concurrency} @title[#:tag "concurrency" #:style 'toc]{Concurrency and Parallelism}
Racket supports multiple threads of control within a program, Racket supports multiple threads of control within a program,
thread-local storage, some primitive synchronization mechanisms, and a thread-local storage, some primitive synchronization mechanisms, and a

View File

@ -5,7 +5,7 @@
@(define future-eval (make-base-eval)) @(define future-eval (make-base-eval))
@(interaction-eval #:eval future-eval (require racket/future)) @(interaction-eval #:eval future-eval (require racket/future))
@title[#:tag "futures"]{Futures for Parallelism} @title[#:tag "futures"]{Futures}
@guideintro["effective-futures"]{futures} @guideintro["effective-futures"]{futures}
@ -19,7 +19,7 @@ Racket.}
The @racket[future] and @racket[touch] functions from The @racket[future] and @racket[touch] functions from
@racketmodname[racket/future] provide access to parallelism as @racketmodname[racket/future] provide access to parallelism as
supported by the hardware and operation system. supported by the hardware and operating system.
In contrast to @racket[thread], which provides concurrency for In contrast to @racket[thread], which provides concurrency for
arbitrary computations without parallelism, @racket[future] provides arbitrary computations without parallelism, @racket[future] provides
parallelism for limited computations. A future executes its work in parallelism for limited computations. A future executes its work in

View File

@ -1,6 +1,6 @@
#lang scribble/doc #lang scribble/doc
@title[#:tag "places"]{@bold{Places}: Coarse-grained Parallelism} @title[#:tag "places"]{Places}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@ -12,70 +12,53 @@
racket/base racket/base
racket/contract racket/contract
racket/place racket/place
racket/flonum)) racket/future
racket/flonum
racket/fixnum))
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@deftech{Places} enable the development of parallel programs that @margin-note{Parallel support for @racket[place] is currently disabled by
take advantage of machines with multiple processors, cores, or default. Enable places by supplying @DFlag{enable-places} to
hardware threads. @exec{configure} when building Racket.}
@note-lib[racket/place] @note-lib[racket/place]
Note: currently, parallel support for @racket[place] is disabled by @tech{Places} enable the development of parallel programs that
default, and using it will raise an exception. Support can only be take advantage of machines with multiple processors, cores, or
enabled if you build Racket yourself, and pass @DFlag{enable-places} to hardware threads.
@exec{configure}. This works only for @exec{racket} (not
@exec{gracket}), and it is supported only on Linux x86/x86_64, and Mac
OS X x86/x86_64 platforms.
@defproc[(place [module-path module-path?] [start-proc symbol?]) place?]{ A @deftech{place} is a parallel task that is effectively a separate
Starts running @racket[start-proc] in parallel. @racket[start-proc] must instance of the Racket virtual machine. Places communicate through
be a function defined in @racket[module-path]. The @racket[place] @deftech{place channels}, which are endpoints for a two-way buffered
procedure returns immediately with a place descriptor value representing the newly constructed place. communication.
Each place descriptor value is also a @racket[place-channel] that permits communication with the place.
}
@defproc[(place-wait [p place?]) exact-integer?]{ To a first approximation, place channels allow only immutable values
Returns the return value of a completed place @racket[p], blocking until as messages over the channel: numbers, characters, booleans, immutable
the place completes (if it has not already completed). pairs, immutable vectors, and immutable structures. In addition, place
} channels themselves can be sent across channels to establish new
(possibly more direct) lines of communication in addition to any
existing lines. Finally, mutable values produced by
@racket[shared-flvector], @racket[make-shared-flvector],
@racket[shared-fxvector], @racket[make-shared-fxvector],
@racket[shared-bytes], and @racket[make-shared-bytes] can be sent
across place channels; mutation of such values is visible to all
places that share the value, because they are allowed in a
@deftech{shared memory space}.
@defproc[(place? [x any/c]) boolean?]{ A @tech{place channel} can be used as a @tech{synchronizable event}
Returns @racket[#t] if @racket[x] is a place-descriptor value, @racket[#f] otherwise. (see @secref["sync"]) to receive a value through the channel. A place
} can also receive messages with @racket[place-channel-recv], and
messages can be sent with @racket[place-channel-send].
@defproc[(place-channel) (values place-channel? place-channel?)]{ Constraints on messages across a place channel---and therefore on the
Returns two @racket[place-channel] endpoint objects. kinds of data that places share---enable greater parallelism than
@racket[future], even including separate @tech{garbage collection} of
separate places. At the same time, the setup and communication costs
for places can be higher than for futures.
One @racket[place-channel] endpoint should be used by the current @racket[place] to send For example, the following expression lanches two places, echoes a
messages to a destination @racket[place]. message to each, and then waits for the places to complete and return:
The other @racket[place-channel] endpoint should be sent to a destination @racket[place] over
an existing @racket[place-channel].
}
@defproc[(place-channel-send [ch place-channel?] [x any/c]) void]{
Sends an immutable message @racket[x] on channel @racket[ch].
}
@defproc[(place-channel-recv [p place-channel?]) any/c]{
Returns an immutable message received on channel @racket[ch].
}
@defproc[(place-channel? [x any/c]) boolean?]{
Returns @racket[#t] if @racket[x] is a place-channel object.
}
@defproc[(place-channel-send/recv [ch place-channel?] [x any/c]) void]{
Sends an immutable message @racket[x] on channel @racket[ch] and then
waits for a repy message.
Returns an immutable message received on channel @racket[ch].
}
@section[#:tag "example"]{Basic Example}
This code launches two places, echos a message to them and then waits for the places to complete and return.
@racketblock[ @racketblock[
(let ([pls (for/list ([i (in-range 2)]) (let ([pls (for/list ([i (in-range 2)])
@ -87,48 +70,75 @@ This code launches two places, echos a message to them and then waits for the pl
(map place-wait pls)) (map place-wait pls))
] ]
This is the code for the place-worker.ss module that each place will execute. The @filepath{place-worker.rkt} module must export the
@racket[place-main] function that each place executes, where
@racket[place-main] must accept a single @tech{place channel}
argument:
@racketblock[ @racketmod[
(module place-worker racket racket
(provide place-main) (provide place-main)
(define (place-main ch) (define (place-main ch)
(place-channel-send ch (format "Hello from place ~a" (place-channel-recv ch))))) (place-channel-send ch (format "Hello from place ~a"
(place-channel-recv ch))))
] ]
@section[#:tag "place-channels"]{Place Channels}
Place channels can be used with @racket[place-channel-recv], or as a
@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{synchronizable event}
(see @secref[#:doc '(lib "scribblings/reference/reference.scrbl") "sync"]) to receive a value
through the channel. The channel can be used with @racket[place-channel-send]
to send a value through the channel.
@section[#:tag "messagepassingparallelism"]{Message Passing Parallelism} @defproc[(place? [x any/c]) boolean?]{
Returns @racket[#t] if @racket[x] is a @deftech{place descriptor}
value, @racket[#f] otherwise. Every @tech{place descriptor}
is also a @tech{place channel}.
}
Places communicate by passing messages on place-channels. @defproc[(place-channel? [x any/c]) boolean?]{
Only atomic values, immutable pairs, vectors, and structs can be Returns @racket[#t] if @racket[x] is @tech{place channel},
communicated across places channels. @racket[#f] otherwise.
}
@section[#:tag "places-architecture"]{Architecture and Garbage Collection} @defproc[(place [module-path module-path?] [start-proc symbol?]) place?]{
Places enables a @deftech{shared memory space} between all places. Creates a @tech{place} to run the procedure that is identified by
References from the @tech{shared memory space} back into a places memory space. @racket[module-path] and @racket[start-proc]. The result is a
The invariant of allowing no backpointers is enforced by only allowing immutable @tech{place descriptor} value that represents the new parallel task;
datastructures to be deep copied into the @tech{shared memory space}. the place descriptor is returned immediately. The place descriptor
value is also a @tech{place channel} that permits communication with
the place.
However, mutation of atomic values in The module indicated by @racket[module-path] must export a function
the @tech{shared memory space} is permitted to improve performace of with the name @racket[start-proc]. The function must accept a single
shared-memory parallel programs. argument, which is a @tech{place channel} that corresponds to the
other end of communication for the @tech{place descriptor} returned
by @racket[place].}
Special functions such as @racket[shared-flvector] and @racket[shared-bytes] allocate
vectors of mutable atomic values into the @tech{shared memory space}.
Parallel mutation of these atomic values @defproc[(place-wait [p place?]) exact-integer?]{
can possibly lead to data races, but will not cause @exec{racket} to Returns the completion value of the place indicated by @racket[p],
crash. In practice however, parallel tasks usually write to disjoint blocking until the place completes if it has not already completed.
partitions of a shared vector. }
Places are allowed to garbage collect independently of one another.
The shared-memory collector, however, has to pause all @defproc[(place-channel) (values place-channel? place-channel?)]{
places before it can collect garbage.
Returns two @tech{place channels}. Data send through the first
channel can be received through the second channel, and data send
through the second channel can be received from the first.
Typically, one place channel is used by the current @tech{place} to
send messages to a destination @tech{place}; the other place channel
us sent to the destination @tech{place} (via an existing @tech{place
channel}).
}
@defproc[(place-channel-send [ch place-channel?] [v any/c]) void]{
Sends a message @racket[v] on channel @racket[ch].
}
@defproc[(place-channel-recv [p place-channel?]) any/c]{
Returns a message received on channel @racket[ch].
}
@defproc[(place-channel-send/recv [ch place-channel?] [v any/c]) void]{
Sends an immutable message @racket[v] on channel @racket[ch] and then
waits for a reply message on the same channel.
}