1

我想将任务映射到三个线程,如下所示:

  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. 如果 、 、 和 中的任何一个taskA完成taskBtaskC并且另一个任务至少有一个未启动的子任务,则与已完成任务关联的线程应该窃取未启动的子任务。

我无法实现此设置。我所能做的就是做以下 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

0

您可以使用线程 ID 来构建工作分配:

#pragma omp parallel num_threads(3)
{
 int tid = omp_get_thread_num();

 if (tid == 0) 
   //  Task 0
 } else if (tid == 1) {
   //  Task 1
 } else
   //  Task 2   
}

您可以根据需要设置线程数,并在任务级别引入嵌套。

于 2013-08-27T00:18:01.417 回答