通过并行任务减少OpenMP

时间:2018-11-25 20:19:04

标签: c openmp

我尝试使用并行任务执行约简操作,但始终为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);

2 个答案:

答案 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
}