Barrier

Support for task barriers.

The Barrier type provided in this module can be used to prevent tasks from proceeding until all other related tasks have also reached the barrier.

In the following example, all of the tasks created by the coforall loop will print their "entering the barrier" messages in an unspecified order, then all of the tasks will print their "past the barrier" messages, also in an unspecified order. Because of the barrier, all of the "entering the barrier" messages will be printed before any of the "past the barrier" messages.

use Barrier;

config const numTasks = here.maxTaskPar;
var b = new Barrier(numTasks);

coforall tid in 1..numTasks {
  writeln("Task ", tid, " is entering the barrier");
  b.barrier();
  writeln("Task ", tid, " is past the barrier");
}

delete b;

Future direction

In the future, we expect to add more language-level support for a "task-team" concept. A task-team will more directly support collective operations such as barriers between the tasks within a team.

The Barrier type is currently implemented as a class, requiring it to be explicitly deleted before it goes out of scope. It is expected that this type will be changed into a record allowing it to be automatically reclaimed. When this change happens, code that uses this Barrier will need to have the explicit deletes removed, but should require no other changes.

The current implementation is designed for correctness, but is not expected to perform well at scale. We expect performance at scale to improve as this barrier implementation is optimized and as the task-team concept is implemented and optimized.

enum BarrierType { Atomic, Sync }

An enumeration of the different barrier implementations. Used to choose the implementation to use when constructing a new barrier object.

  • BarrierType.Atomic uses Chapel atomic variables to control the barrier.
  • BarrierType.Sync uses Chapel sync variables to control the barrier.
class Barrier

A barrier that will cause numTasks to wait before proceeding.

proc Barrier(numTasks: int, barrierType: BarrierType = BarrierType.Atomic, reusable: bool = barrierType==BarrierType.Atomic)

Construct a new barrier object.

Arguments:
  • numTasks -- The number of tasks that will use this barrier
  • barrierType -- The barrier implementation to use
  • reusable -- Incur some extra overhead to allow reuse of this barrier?
proc barrier()

Block until all related tasks have called this method. If reusable is true, reset the barrier to be used again.

proc notify()

Notify the barrier that this task has reached this point.

proc wait()

Wait until n tasks have called notify. If reusable is true, reset the barrier to be used again. Note: if reusable is true wait will block until n tasks have called it after calling notify.

proc try(): bool

return true if n tasks have called notify