简体   繁体   English

使用并行任务减少 OpenMP

[英]OpenMP reduction with parallel task

I tried to use parallel task to perform reduction, but always get 0. Here is my code:我尝试使用并行任务来执行归约,但总是得到 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);

But when I use parallel for, the result is right, which is 50. Can anyone tell me how to modify the parallel task code?但是当我使用parallel for时,结果是对的,是50。谁能告诉我如何修改并行任务代码? This is my parallel for code, which works well:这是我的代码并行,效果很好:

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);

According to the OpenMP standard 4.5 , you cannot reduce a variable that is used in the task constructor.根据OpenMP 标准 4.5 ,您不能减少任务构造函数中使用的变量。

A list item that appears in a reduction clause of the innermost enclosing worksharing or parallel construct may not be accessed in an explicit task.在显式任务中可能无法访问出现在最内部封闭工作共享或并行构造的归约子句中的列表项。

Nevertheless, it looks like that feature will be covered by OpenMP 5.0.尽管如此,该功能似乎将被 OpenMP 5.0 覆盖。 Looking at your code the better approach is actually to use the parallel for with the reduction clause, anyway.无论如何,查看您的代码的更好方法实际上是将 parallel for 与 reduce 子句一起使用。

dreamcrash's answer is spot on. Dreamcrash 的答案是正确的。 OpenMP 5.0 has added task reduction support, but OpenMP 5.0 is not widely supported yet, afaik only the Intel compiler supports a preview of OpenMP 5.0 that includes task reduction. OpenMP 5.0 增加了任务缩减支持,但 OpenMP 5.0 尚未得到广泛支持,只有英特尔编译器支持包含任务缩减的 OpenMP 5.0 预览版。

If you really must use reduction with tasks with OpenMP previous to 5.0, you can basically declare the reduction variable as threadprivate and do a manual reduction as outlined in this talk .如果您确实必须对 OpenMP 5.0 之前的任务使用缩减,您基本上可以将缩减变量声明为threadprivate并按照本演讲中的概述进行手动缩减。

It would look something like this:它看起来像这样:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM