Class IntegerForLoop
- Direct Known Subclasses:
ReciprocalSpace.BSplineRegion.BSplineLoop
,RowLoop
,SliceLoop
,SpatialDensityLoop
int
. The loop stride is implicit (+1).
To execute a parallel for loop, create a ParallelRegion object;
create an instance of a concrete subclass of class IntegerForLoop; and pass
this instance to the parallel region's execute()
method. Either
every parallel team thread must call the parallel region's execute()
method with identical arguments, or every thread must not call the
execute()
method. You can do all this using an anonymous inner
class; for example:
new ParallelRegion() { . . . public void run() { . . . execute (0, 99, new IntegerForLoop() { // Thread local variable declarations . . . public void start() { // Per-thread pre-loop initialization code . . . } public void run (int first, int last) { // Loop code . . . } public void finish() { // Per-thread post-loop finalization code . . . } }); } . . . }
The parallel region's execute()
method does the following. Each
parallel team thread calls the parallel for loop's start()
method
once before beginning any loop iterations. The range of loop indexes is
divided into "chunks" and the chunks are apportioned among the threads, in a
manner determined by the parallel for loop's schedule as returned by the
schedule()
method. Each thread repeatedly calls the parallel for
loop's run()
method, passing in a different chunk on each call,
until all the chunks assigned to that thread have been performed. When a
thread has finished calling run()
, the thread calls the parallel for
loop's finish()
method. Then the thread waits at an implicit
barrier. When all the threads have reached the barrier, the
execute()
method returns.
Note that each parallel team thread actually creates its own instance of the
parallel for loop class and passes that instance to the parallel region's
execute()
method. Thus, any fields declared in the parallel for loop
class will not be shared by all the threads, but instead will be
private to each thread.
The start()
method is intended for performing per-thread
initialization before starting the loop iterations. If no such initialization
is needed, omit the start()
method.
The run()
method contains the code for the loop. The first and last
indexes for a chunk of loop iterations are passed in as arguments. The loop
stride is implicit (+1). The parallel for loop's run()
method must
be coded this way:
public void run (int first, int last) { for (int i = first; i <= last; ++ i) { // Loop body code . . . } }with the loop indexes running from
first
to last
inclusive and increasing by +1 on each iteration.
The finish()
method is intended for performing per-thread
finalization after finishing the loop iterations. If no such finalization is
needed, omit the finish()
method.
Sometimes a portion of a parallel for loop has to be executed sequentially in
the order of the loop indexes, while the rest of the parallel for loop can be
executed concurrently. For example, the loop body is performing some
computation that can be executed in parallel for different loop indexes, but
the results of each computation must be written to a file sequentially in the
order of the loop indexes. The ordered()
method is provided for this
purpose. A call to the ordered()
method may appear once in the
parallel for loop's run()
method, like so:
public void run (int first, int last) { for (int i = first; i <= last; ++ i) { // This portion executed concurrently . . . ordered (new ParallelSection() { public void run() { // This portion executed sequentially // in the order of the loop indexes . . . } }); // This portion executed concurrently again . . . } }When called, the
ordered()
method waits until the
ordered()
method has been called and has returned in all loop iterations prior to the
current loop iteration. Then the ordered()
method calls the given
parallel section's run()
method. When the parallel section's
run()
method returns, the ordered()
method returns. If the
parallel section's run()
method throws an exception, the
ordered()
method throws that same exception.
It is possible to stop a parallel for loop using the stopLoop()
method, like this:
public void run (int first, int last) { for (int i = first; i <= last; ++ i) { // Loop body . . . if (/*time to stop the loop*/) { stopLoop(); break; } // More loop body . . . } }Once
stopLoop()
is called, after each parallel team thread
finishes executing its current chunk of iterations, each thread will execute
no further chunks and will proceed to finish the parallel for loop. Note well
that stopping a parallel for loop is not the same as executing a
break
statement in a regular for loop. The parallel for loop does
not stop until each thread, including the thread that called
stopLoop()
, has finished its current chunk of iterations.
Thus, depending on the parallel for loop's schedule, additional iterations
may be executed after stopLoop()
is called. (The break
statement in the above example causes the thread that called
stopLoop()
to finish its chunk of iterations early.)
Normally, at the end of the parallel for loop, the parallel team threads wait
for each other at a barrier. To eliminate this barrier wait, include
BarrierAction.NO_WAIT
in the execute()
method call:
new ParallelRegion() { . . . public void run() { . . . execute (0, 99, new IntegerForLoop() { . . . }, BarrierAction.NO_WAIT); . . . } }To execute a section of code in a single thread as part of the barrier synchronization, include an instance of class BarrierAction in the
execute()
method call. The barrier action object's
run()
method contains the code to be executed in a single thread
while the other threads wait:
new ParallelRegion() { . . . public void run() { . . . execute (0, 99, new IntegerForLoop() { . . . }, new BarrierAction() { public void run() { // Single-threaded code goes here . . . } }); . . . } }For further information, see class BarrierAction.
If the parallel for loop's start()
, run()
, or
finish()
method throws an exception in one of the threads, then that
thread executes no further code in the loop, and the parallel region's
execute()
method throws that same exception in that thread.
Furthermore, the other threads in the parallel team also execute no further
code in the loop after finishing their current chunks. Thus, if one thread
throws an exception, the whole parallel for loop exits with some (perhaps
none) of the iterations unperformed.
- Version:
- 11-Nov-2007
- Author:
- Alan Kaminsky
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
finish()
Perform per-thread finalization actions after finishing the loop iterations.final void
ordered
(ParallelSection theSection) Execute the given section of code in order of the loop indexes.abstract void
run
(int first, int last) Execute one chunk of iterations of this parallel for loop.schedule()
Determine this parallel for loop's schedule.void
start()
Perform per-thread initialization actions before starting the loop iterations.final void
stopLoop()
Stop this parallel for loop.Methods inherited from class edu.rit.pj.ParallelConstruct
getThreadCount, getThreadIndex, isExecutingInParallel, region, team
-
Constructor Details
-
IntegerForLoop
public IntegerForLoop()Construct a new parallel for loop.
-
-
Method Details
-
schedule
Determine this parallel for loop's schedule. The schedule determines how the loop iterations are apportioned among the parallel team threads. For further information, see class IntegerSchedule.The
schedule()
method may be overridden in a subclass to return the desired schedule. If not overridden, the default is a runtime schedule (seeIntegerSchedule.runtime()
).- Returns:
- Schedule for this parallel for loop.
-
start
Perform per-thread initialization actions before starting the loop iterations.The
start()
method may be overridden in a subclass. If not overridden, thestart()
method does nothing. -
run
Execute one chunk of iterations of this parallel for loop. Therun()
method must perform the loop body for indexesfirst
throughlast
inclusive, increasing the loop index by +1 after each iteration.The
run()
method must be overridden in a subclass. -
finish
Perform per-thread finalization actions after finishing the loop iterations.The
finish()
method may be overridden in a subclass. If not overridden, thefinish()
method does nothing. -
ordered
Execute the given section of code in order of the loop indexes. A call to theordered()
method may appear in this parallel for loop'srun()
method. When called, theordered()
method waits until theordered()
method has been called and has returned in all loop iterations prior to the current loop iteration. Then theordered()
method calls therun()
method oftheParallelSection
. When the parallel section'srun()
method returns, theordered()
method returns. If the parallel section'srun()
method throws an exception, theordered()
method throws that same exception.The
ordered()
method is used when a portion of a parallel for loop has to be executed sequentially in the order of the loop indexes, while the rest of the parallel for loop can be executed concurrently.Note: Either the
ordered()
method must be called exactly once during each call of the parallel for loop'srun()
method, or theordered()
method must not be called at all.- Parameters:
theSection
- Parallel section to execute in order.- Throws:
NullPointerException
- (unchecked exception) Thrown iftheSection
is null.IllegalStateException
- (unchecked exception) Thrown if no parallel team is executing this parallel for loop.Exception
- Thrown iftheSection
'srun()
method throws an exception.Exception
- if any.
-
stopLoop
public final void stopLoop()Stop this parallel for loop. OncestopLoop()
is called, after each parallel team thread finishes executing its current chunk of iterations, each thread will execute no further chunks and will proceed to finish this parallel for loop.- Throws:
IllegalStateException
- (unchecked exception) Thrown if no parallel team is executing this parallel for loop.
-