我尝试使用并行任务执行约简操作,但始终为0。这是我的代码:
int sum = 0;
#pragma omp parallel reduction(+:sum)
#pragma omp single
for(int i=0; i<10; i++)
{
#pragma omp task
{
printf("Thread: %d\n", omp_get_thread_num());
int y = 5;
sum += y;
}
}
printf("%d\n", sum);
但是当我使用并列时,结果是正确的,即50。有人可以告诉我如何修改并列任务代码吗? 这是我的代码并行代码,效果很好:
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for(int i=0; i<10; i++)
{
printf("Thread: %d\n", omp_get_thread_num());
int y = 5;
sum += y;
}
printf("%d\n", sum);
答案 0 :(得分:3)
根据OpenMP standard 4.5,您无法减少任务构造函数中使用的变量。
出现在最内层的归约子句中的列表项 封闭的工作共享或并行构造可能无法在 明确的任务。
尽管如此,看起来该功能将被OpenMP 5.0涵盖。在您的代码中查看,更好的方法实际上是在归约子句中使用并行操作。
答案 1 :(得分:1)
dreamcrash的答案是正确的。 OpenMP 5.0添加了任务减少支持,但是OpenMP 5.0尚未得到广泛支持,仅Intel编译器支持包含任务减少的OpenMP 5.0预览。
如果您确实必须对带有5.0之前版本的OpenMP的任务使用归约,则基本上可以将归约变量声明为threadprivate
,并按照this talk中所述进行手动归约。
它看起来像这样:
int sum = 0;
int thread_sum = 0;
#pragma omp threadprivate(sum)
#pragma omp parallel
{
#pragma omp single
for(int i=0; i<10; i++)
{
#pragma omp task
{
printf("Thread: %d\n", omp_get_thread_num());
int y = 5;
thread_sum += y;
}
}
#pragma omp atomic
sum += thread_sum
}