次のように、タスクを 3 つのスレッドにマップします。
taskA
、taskB
、およびのそれぞれは、taskC
別々のスレッドで実行する必要があります。taskA
サブタスクtask(1)
、task(2)
、および がありtask(3)
ます。taskB
サブタスクtask(11)
、task(12)
、および がありtask(13)
ます。taskC
サブタスクtask(21)
、task(22)
、および がありtask(23)
ます。taskA
、taskB
、およびのいずれかがtaskC
終了し、別のタスクの開始されていないサブタスクが少なくとも 1 つある場合、終了したタスクに関連付けられたスレッドは、開始されていないサブタスクをスチールする必要があります。
この設定を達成できませんでした。次のMWEを実行できたのはすべてです。この MWE では、スレッドは規則 2、3、4 に従いません。
ここに私のMWEがあります:
double task(int taskid) {
int tid = omp_get_thread_num();
int nthreads = omp_get_num_threads();
printf("%d/%d: taskid=%d\n", tid, nthreads, taskid);
int i;
double t = 1.1;
for(i = 0; i < 10000000*taskid; i++) {
t *= t/i;
}
return t;
}
double taskA() {
int tid = omp_get_thread_num();
int nthreads = omp_get_num_threads();
printf("%s %d/%d\n", __FUNCTION__, tid, nthreads);
double a, b, c;
//#pragma omp parallel
//#pragma omp single
{
#pragma omp task untied shared(a)
a=task(1);
#pragma omp task untied shared(b)
b=task(2);
#pragma omp task untied shared(c)
c=task(3);
}
return a+b+c;
}
double taskB() {
int tid = omp_get_thread_num();
int nthreads = omp_get_num_threads();
printf("%s %d/%d\n", __FUNCTION__, tid, nthreads);
double a, b, c;
//#pragma omp parallel
//#pragma omp single
{
#pragma omp task untied shared(a)
a=task(11);
#pragma omp task untied shared(b)
b=task(12);
#pragma omp task untied shared(c)
c=task(13);
}
return a+b+c;
}
double taskC() {
int tid = omp_get_thread_num();
int nthreads = omp_get_num_threads();
printf("%s %d/%d\n", __FUNCTION__, tid, nthreads);
double a, b, c;
//#pragma omp parallel
//#pragma omp single
{
#pragma omp task untied shared(a)
a=task(21);
#pragma omp task untied shared(b)
b=task(22);
#pragma omp task untied shared(c)
c=task(23);
}
return a+b+c;
}
int main() {
omp_set_num_threads(3);
double a,b,c;
#pragma omp parallel
#pragma omp single
{
#pragma omp task untied
a=taskA();
#pragma omp task untied
b=taskB();
#pragma omp task untied
c=taskC();
}
#pragma omp taskwait
printf("%g %g %g\n", a, b, c);
return 0;
}
次のようにコンパイル:
icpc -Wall -fopenmp -O2 -o nestedomp nestedomp.c
出力:
taskC 1/3
1/3: taskid=21
taskA 2/3
taskB 0/3
0/3: taskid=23
2/3: taskid=22
1/3: taskid=1
1/3: taskid=2
2/3: taskid=3
0/3: taskid=11
1/3: taskid=12
2/3: taskid=13
ここで、スレッド 0 はタスク 23 の処理を開始しますが、1 または 11 の処理を開始する必要があります。