Go to main content
Oracle® Developer Studio 12.5: OpenMP API User's Guide

Exit Print View

Updated: July 2016
 
 

4.1 OpenMP Tasking Model

Tasking facilitates the parallelization of applications where units of work are generated dynamically, as in recursive structures or while loops.

4.1.1 OpenMP Task Execution

In OpenMP, an explicit task is specified using the task construct, which can be placed anywhere in the program. Whenever a thread encounters a task construct, a new task is generated.

When a thread encounters a task construct, it may choose to execute the task immediately or defer its execution until a later time. If task execution is deferred, then the task is placed in a conceptual pool of tasks that is associated with the current parallel region. The threads in the current team will take tasks out of the pool and execute them until the pool is empty. The thread that executes a task might be different from the thread that originally encountered the task and placed it in the pool.

The code associated with a task is executed only once. A task is tied if the code must be executed by the same thread from beginning to end. A task is untied if the code may be executed by more than one thread, so that different threads execute different parts of the task code. By default, tasks are tied, and a task can be specified to be untied by using the untied clause on the task directive.

Threads are allowed to suspend the execution of a task region at a task scheduling point in order to execute a different task. If the suspended task is tied, then the same thread later resumes execution of the suspended task. If the suspended task is untied, then any thread in the current team may resume the task execution.

Task scheduling points are implied at a number of locations, including the following:

  • The point immediately following the generation of an explicit task

  • After the point of completion of a task region

  • In a taskyield region

  • In a taskwait region

  • At the end of a taskgroup region

  • In an implicit and explicit barrier region

In addition to explicit tasks specified using the task construct, the OpenMP specification presents the notion of implicit tasks. An implicit task is a task generated by the implicit parallel region, or generated when a parallel construct is encountered during execution. In the latter case, the code for each implicit task is the code inside the parallel construct. Each implicit task is assigned to a different thread in the team and is tied.

All implicit tasks generated when a parallel construct is encountered are guaranteed to be complete when the master thread exits the implicit barrier at the end of the parallel region. On the other hand, all explicit tasks generated within a parallel region are guaranteed to be complete on exit from the next implicit or explicit barrier within the parallel region.

4.1.2 OpenMP Task Types

The OpenMP specification defines various types of tasks that the programmer may use to reduce the overhead of tasking.

An undeferred is a task for which execution is not deferred with respect to the generating task; that is, the generating task region is suspended until execution of the undeferred task is completed. The undeferred task might not be executed immediately by the encountering thread. It might be placed in a pool and executed at a later time by the encountering thread or by some other thread. Once the execution of the task is completed, the generating task can resume. An example of an undeferred task is a task with an if clause expression that evaluates to false. In this case, an undeferred task is generated and the encountering thread must suspend the current task region. Execution of the current task region cannot be resumed until the task with the if clause is completed.

Unlike an undeferred task, an included task is executed immediately by the encountering thread and is not placed in the pool to be executed at a later time. The task's execution is sequentially included in the generating task region. As with undeferred tasks, the generating task is suspended until the execution of the included task is completed, at which point the generating task can resume. An example of an included task is a task that is a descendant of a final task.

A merged task is a task whose data environment is the same as that of its generating task region. If a mergeable clause is present on a task directive, and the generated task is an undeferred task or an included task, then the implementation may choose to generate a merged task instead. If a merged task is generated, then the behavior is as though there was no task directive at all.

A final task is a task that forces all of its descendent tasks to become final and included tasks. When a final clause is present on a task directive and the final clause expression evaluates to true, the generated task will be a final task.