且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

什么时候需要减少?

更新时间:2022-06-22 22:28:50

如果没有归约条款,您发布的代码不正确.

The code you posted is not correct without the reduction clause.

sum += matrixA[i][j];

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

Will cause a classic race condition when executed by multiple threads in parallel. Sum is a shared variable, but sum += ... is not an atomic operation.

(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变量将被设置为所有线程本地副本的总和(以无竞争条件的正确方式).

The reduction fixes exactly this. With reduction, the loop will work on an implicit thread-local copy of the sum variable. At the end of the region, the original sum variable will be set to the sum of all thread-local copies (in a correct way without race-conditions).

另一种解决方案是将sum += ...标记为原子操作或关键部分.但是,这会带来很大的性能损失.

Another solution would be to mark the sum += ... as atomic operation or critical section. That, however has a significant performance penalty.