我想将任务映射到三个线程,如下所示:
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
中的任何一个完成且至少有一个未启动的另一个任务的子任务,则与完成的任务相关联的线程应该窃取未开始的子任务。
我无法实现此设置。我只能做以下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.
答案 0 :(得分: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
}
您可以根据需要设置线程数,并在任务级别引入嵌套。