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
@(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,
thread-local storage, some primitive synchronization mechanisms, and a

View File

@ -5,7 +5,7 @@
@(define future-eval (make-base-eval))
@(interaction-eval #:eval future-eval (require racket/future))
@title[#:tag "futures"]{Futures for Parallelism}
@title[#:tag "futures"]{Futures}
@guideintro["effective-futures"]{futures}
@ -19,7 +19,7 @@ Racket.}
The @racket[future] and @racket[touch] functions from
@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
arbitrary computations without parallelism, @racket[future] provides
parallelism for limited computations. A future executes its work in

View File

@ -1,6 +1,6 @@
#lang scribble/doc
@title[#:tag "places"]{@bold{Places}: Coarse-grained Parallelism}
@title[#:tag "places"]{Places}
@; ----------------------------------------------------------------------
@ -12,70 +12,53 @@
racket/base
racket/contract
racket/place
racket/flonum))
racket/future
racket/flonum
racket/fixnum))
@; ----------------------------------------------------------------------
@deftech{Places} enable the development of parallel programs that
take advantage of machines with multiple processors, cores, or
hardware threads.
@margin-note{Parallel support for @racket[place] is currently disabled by
default. Enable places by supplying @DFlag{enable-places} to
@exec{configure} when building Racket.}
@note-lib[racket/place]
Note: currently, parallel support for @racket[place] is disabled by
default, and using it will raise an exception. Support can only be
enabled if you build Racket yourself, and pass @DFlag{enable-places} to
@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.
@tech{Places} enable the development of parallel programs that
take advantage of machines with multiple processors, cores, or
hardware threads.
@defproc[(place [module-path module-path?] [start-proc symbol?]) place?]{
Starts running @racket[start-proc] in parallel. @racket[start-proc] must
be a function defined in @racket[module-path]. The @racket[place]
procedure returns immediately with a place descriptor value representing the newly constructed place.
Each place descriptor value is also a @racket[place-channel] that permits communication with the place.
}
A @deftech{place} is a parallel task that is effectively a separate
instance of the Racket virtual machine. Places communicate through
@deftech{place channels}, which are endpoints for a two-way buffered
communication.
@defproc[(place-wait [p place?]) exact-integer?]{
Returns the return value of a completed place @racket[p], blocking until
the place completes (if it has not already completed).
}
To a first approximation, place channels allow only immutable values
as messages over the channel: numbers, characters, booleans, immutable
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?]{
Returns @racket[#t] if @racket[x] is a place-descriptor value, @racket[#f] otherwise.
}
A @tech{place channel} can be used as a @tech{synchronizable event}
(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?)]{
Returns two @racket[place-channel] endpoint objects.
One @racket[place-channel] endpoint should be used by the current @racket[place] to send
messages to a destination @racket[place].
Constraints on messages across a place channel---and therefore on the
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.
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.
For example, the following expression lanches two places, echoes a
message to each, and then waits for the places to complete and return:
@racketblock[
(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))
]
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[
(module place-worker racket
(provide place-main)
@racketmod[
racket
(provide place-main)
(define (place-main ch)
(place-channel-send ch (format "Hello from place ~a" (place-channel-recv ch)))))
(define (place-main 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.
Only atomic values, immutable pairs, vectors, and structs can be
communicated across places channels.
@defproc[(place-channel? [x any/c]) boolean?]{
Returns @racket[#t] if @racket[x] is @tech{place channel},
@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.
References from the @tech{shared memory space} back into a places memory space.
The invariant of allowing no backpointers is enforced by only allowing immutable
datastructures to be deep copied into the @tech{shared memory space}.
Creates a @tech{place} to run the procedure that is identified by
@racket[module-path] and @racket[start-proc]. The result is a
@tech{place descriptor} value that represents the new parallel task;
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 @tech{shared memory space} is permitted to improve performace of
shared-memory parallel programs.
The module indicated by @racket[module-path] must export a function
with the name @racket[start-proc]. The function must accept a single
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
can possibly lead to data races, but will not cause @exec{racket} to
crash. In practice however, parallel tasks usually write to disjoint
partitions of a shared vector.
@defproc[(place-wait [p place?]) exact-integer?]{
Returns the completion value of the place indicated by @racket[p],
blocking until the place completes if it has not already completed.
}
Places are allowed to garbage collect independently of one another.
The shared-memory collector, however, has to pause all
places before it can collect garbage.
@defproc[(place-channel) (values place-channel? place-channel?)]{
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.
}