OpenMP 4.0 仕様では、task ディレクティブの depend 節を紹介しています。これは、タスクのスケジューリングに対する追加の制約を強制するものです。これらの制約では、兄弟タスク間の依存関係のみを確立します。兄弟タスクとは、同じタスク領域の子タスクである OpenMP タスクです。
in 依存関係タイプを depend 節で指定すると、生成されたタスクは、out または inout 依存関係タイプリスト内の少なくともいずれか 1 つのリスト項目を参照する、以前に生成されたすべての兄弟タスクの従属タスクとなります。out または inout 依存関係タイプを depend 節で指定すると、生成されたタスクは、in、out、または inout 依存関係タイプリスト内の少なくともいずれか 1 つのリスト項目を参照する、以前に生成されたすべての兄弟タスクの従属タスクとなります。
次の例はタスクの依存関係を示しています。
使用例 4-3 兄弟タスクのみを同期化する depend 節の例% cat -n task_depend_01.c 1 #include <omp.h> 2 #include <stdio.h> 3 #include <unistd.h> 4 5 int main() 6 { 7 int a,b,c; 8 9 #pragma omp parallel 10 { 11 #pragma omp master 12 { 13 #pragma omp task depend(out:a) 14 { 15 #pragma omp critical 16 printf ("Task 1\n"); 17 } 18 19 #pragma omp task depend(out:b) 20 { 21 #pragma omp critical 22 printf ("Task 2\n"); 23 } 24 25 #pragma omp task depend(in:a,b) depend(out:c) 26 { 27 printf ("Task 3\n"); 28 } 29 30 #pragma omp task depend(in:c) 31 { 32 printf ("Task 4\n"); 33 } 34 } 35 if (omp_get_thread_num () == 1) 36 sleep(1); 37 } 38 return 0; 39 } % cc -xopenmp -O3 task_depend_01.c % a.out Task 2 Task 1 Task 3 Task 4 % a.out Task 1 Task 2 Task 3 Task 4
この例では、Task 1、2、3、および 4 はすべて同じ暗黙的タスク領域の子タスクであるため、それらは兄弟タスクです。a 引数への依存関係が depend 節に指定されているため、Task 3 は Task 1 と 2 の従属タスクです。したがって、Task 1 と 2 の両方が完了するまで、Task 3 をスケジュールすることはできません。同様に、Task 4 は Task 3 の従属タスクであるため、Task 3 が完了するまで Task 4 をスケジュールすることはできません。
depend 節は兄弟タスクのみを同期化することに注意してください。次の例 (Example 4–4) は、depend 節が兄弟以外のタスクに影響を及ぼさないケースを示しています。
使用例 4-4 兄弟以外のタスクに影響を及ぼさない depend 節の例% cat -n task_depend_02.c 1 #include <omp.h> 2 #include <stdio.h> 3 #include <unistd.h> 4 5 int main() 6 { 7 int a,b,c; 8 9 #pragma omp parallel 10 { 11 #pragma omp master 12 { 13 #pragma omp task depend(out:a) 14 { 15 #pragma omp critical 16 printf ("Task 1\n"); 17 } 18 19 #pragma omp task depend(out:b) 20 { 21 #pragma omp critical 22 printf ("Task 2\n"); 23 24 #pragma omp task depend(out:a,b,c) 25 { 26 sleep(1); 27 #pragma omp critical 28 printf ("Task 5\n"); 29 } 30 } 31 32 #pragma omp task depend(in:a,b) depend(out:c) 33 { 34 printf ("Task 3\n"); 35 } 36 37 #pragma omp task depend(in:c) 38 { 39 printf ("Task 4\n"); 40 } 41 } 42 if (omp_get_thread_num () == 1) 43 sleep(1); 44 } 45 return 0; 46 } % cc -xopenmp -O3 task_depend_02.c % a.out Task 1 Task 2 Task 3 Task 4 Task 5
上記の例では、Task 5 は Task 2 の子タスクであり、Task 1、2、3、または 4 の兄弟ではありません。このため、depend 節が同じ変数 (a、b、c) を参照しているにもかかわらず、Task 5 と Task 1、2、3、または 4 の間に依存関係はありません。