Revise places docs to fit the reference-manual style
This commit is contained in:
parent
af318c4501
commit
5c89df2f7f
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user