1

次のように、タスクを 3 つのスレッドにマップします。

  1. taskAtaskB、およびのそれぞれは、taskC別々のスレッドで実行する必要があります。

  2. taskAサブタスクtask(1)task(2)、および がありtask(3)ます。

  3. taskBサブタスクtask(11)task(12)、および がありtask(13)ます。

  4. taskCサブタスクtask(21)task(22)、および がありtask(23)ます。

  5. taskAtaskB、およびのいずれかが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 の処理を​​開始する必要があります。

4

1 に答える 1