3
int main()
{
    int a=0;
    omp_set_num_threads(2);
    #pragma omp parallel reduction(+ : a)
    {
        a = omp_get_thread_num()+1;
    }
    std::cout << "Output:" << a;
    return 1;
}

I am getting wrong output using openmp reduction... For the following code, reduction(+) gives the output of sum of threadnum(), but when i mention reduction (-), it gives the same output... I am getting output as 3 for "+" and "-".

4

2 回答 2

8

OpenMP 中的归约函数如下:每个线程都被赋予其归约变量的本地副本+=以及-=影响本地副本等操作。然后在最后执行以下归约操作:

a = init_value op a_0 op a_1 op a_2 op ... op a_(N-1)

其中N是线程数,init_value是归约操作的初始化值。+和归约操作的初始化值-都是 0(零)。不过,减法有一个问题,它在 OpenMP 标准中作为对最终值形成方式的注释进行了解释(第 2.9.3.6 节reduction):

(将减法归约的部分结果相加形成最终值。)

这意味着reduction(-:a)您仍然可以将所有私有值加在一起,即两者+-归约是等价的。这是实现它的正确方法,因为假设-归约只会与var -= exprorvar = var - expr表达式耦合。因此,您的程序不符合标准,并且您会因为没有阅读 OpenMP 的复杂细节而得到应得的结果。

正确的例子reduction(-:a)是:

#pragma omp parallel reduction(-:a)
{
    a -= omp_get_thread_num() + 1;
}
于 2013-05-15T12:28:53.163 回答
0

由于减法运算符的非交换性,减少-总是很棘手......你最好将所有内容相加,然后否定结果;任何阅读代码的人都将清楚,而不必求助于阅读标准!

于 2013-05-15T12:42:31.613 回答