什么时候需要减少?

时间:2016-11-26 14:01:49

标签: c openmp

我写过这个读取矩阵的代码,它基本上总结了矩阵的值...但我的问题是,因为我尝试用不同的方式编写pragma,我发现{{1没有必要,但是,我只是不知道为什么,在这种情况下,我可能已经错过了减少系统的实际意义。这将是另一种选择:reduction (+:sum)

这就是代码:

#pragma omp parallel for private(i, j) reduction (+:sum)

而且,我想问一下,如果有更好的解决方案,那就是更好的解决方案,因为我认为这是最有效的方式。

1 个答案:

答案 0 :(得分:5)

如果没有减少条款,您发布的代码不正确。

sum += matrixA[i][j];

并行执行多个线程时会导致经典竞争条件。 Sum是一个共享变量,但sum += ...不是原子操作。

(sum is initially 0, all matrix elements 1)
Thread 1                     |  Thread 2
-----------------------------------------------------------
tmp = sum + matrix[0][0] = 1 |
                             | tmp = sum + matrix[1][0] = 1
sum = tmp = 1                |
                             | sum = tmp = 1 (instead of 2)

缩减确切地说明了这一点。通过缩减,循环将在sum变量的隐式线程局部副本上工作。在该区域的末尾,原始的sum变量将被设置为所有线程局部副本的总和(以没有竞争条件的正确方式)。

另一种解决方案是将sum += ...标记为原子操作或关键部分。然而,这会对性能造成重大损失。