タスク化を利用すると、再帰的な構造や while ループのように、作業単位が動的に生成されるようなアプリケーションの並列化が容易になります。
OpenMP では、プログラム内の任意の場所に配置できる task 構文を使用して明示的タスクを指定します。スレッドが task 構文を検出すると、新しいタスクが生成されます。
スレッドは、task 構文が検出されると、それをただちに実行するか、実行を延期してあとで実行するかを選択できます。タスクの実行が延期される場合、そのタスクは現在の並列領域に関連付けられた概念上のタスクプールに入れられます。現在のチームに属するスレッドは、プールからタスクを取り出し実行するという処理を、プールが空になるまで繰り返します。タスクを実行するスレッドが、最初にタスクを検出してプールに入れたスレッドとは異なる場合があります。
タスクに関連付けられたコードは 1 回だけ実行されます。コードを最初から最後まで同じスレッドで実行する必要がある場合、タスクは結合されます。コードを複数のスレッドで実行してもかまわない場合、タスクは結合解除され、タスクコードのさまざまな部分が異なるスレッドで実行されます。デフォルトではタスクは結合されており、タスクが結合解除されるように指定するには、task ディレクティブで untied 節を使用します。
スレッドは、異なるタスクを実行するためにタスクスケジューリングポイントでタスク領域の実行を中断できます。中断されたタスクが結合されている場合は、同じスレッドにより中断されたタスクの実行が後に再開されます。中断されたタスクが結合されていない場合は、現在のチームに属するスレッドならどれでもタスクの実行を再開できます。
タスクスケジューリングポイントは、次を含むいくつかの場所で暗黙的に定義されます。
明示的タスクの生成直後のポイント
task 領域の完了ポイントのあと
taskyield 領域内
taskwait 領域内
taskgroup 領域の終わり
暗黙的および明示的な barrier 領域内
OpenMP 仕様では、task 構文を使って指定する明示的タスクに加え、暗黙的タスクの概念も説明されています。暗黙的タスクとは、暗黙的な並列領域によって生成されるタスク、または実行中に parallel 構文が検出されたときに生成されるタスクです。後者の場合、それぞれの暗黙的タスクのコードは parallel 構文の内部コードになります。それぞれの暗黙的タスクは、チーム内の異なるスレッドに割り当てられ、結合されます。
parallel 構文が検出されたときに生成されたすべての暗黙的タスクは、マスタースレッドが並列領域の最後で暗黙的バリアーを終了するときに完了することが保証されます。一方、並列領域内に生成されるすべての明示的タスクは、並列領域内の次の暗黙的または明示的バリアーの終了時に完了することが保証されます。
OpenMP 仕様には、タスク化のオーバーヘッドを減らすためにプログラマが使用できる各種のタスクが定義されています。
非延期タスクとは、その生成元タスクに対して実行が延期されないタスクです。つまり、生成元タスク領域は非延期タスクの実行が完了するまで中断されます。非延期タスクはそれを検出したスレッドによってただちに実行されない場合があります。プールに入れられ、検出したスレッドまたはほかのスレッドによってあとで実行される場合があります。そのタスクの実行が完了したら、生成元タスクが再開できます。非延期タスクの一例は、false と評価される if 節の式を含むタスクです。この場合、非延期タスクが生成され、検出したスレッドは現在のタスク領域を中断する必要があります。現在のタスク領域の実行は、if 節を含むタスクが完了するまで再開できません。
非延期タスクとは異なり、インクルードタスクは検出したスレッドによってただちに実行されるため、あとで実行するためにプールに入れられることはありません。このタスクの実行は、生成元タスク領域に順次追加されます。非延期タスクと同様に、生成元タスクはインクルードタスクの実行が完了するまで中断され、完了した時点で再開できます。インクルードタスクの一例は、最終タスクの子孫であるタスクです。
マージタスクとは、その生成元タスク領域と同じデータ環境を持つタスクです。task ディレクティブに mergeable 節が存在し、生成されるタスクが非延期タスクまたはインクルードタスクの場合、実装では代わりにマージタスクの生成を選択できます。マージタスクが生成される場合は、task ディレクティブがまったく存在しないかのように動作します。
最終タスクとは、そのすべての子孫タスクが最終タスクおよびインクルードタスクになるように強制するタスクです。task ディレクティブに final 節が存在し、final 節の式が true と評価される場合、生成されるタスクは最終タスクになります。