什么时候需要减少?

mag*_*nyo 2 c openmp

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

这将是代码:

#include <stdio.h>
#include <math.h>
#include <omp.h>
#include <unistd.h>


int main ()
{

    printf("===MATRIX SUM===\n");
    printf("N ROWS: ");
    int i1; scanf("%d",&i1);
    printf("M COLUMNS: ");
    int j1; scanf("%d",&j1);
    int matrixA[i1][j1];

    int i, j;

    for(i = 0; i < i1; i++){
        for (j = 0; j < j1; j++){
            scanf("%d",&matriuA[i][j]);
        }
    }

    printf("\nMATRIX A: \n");
    for (i = 0; i < i1; i++){
        for (j = 0; j < j1; j++){
            printf("%d ", matrixA[i][j]);
        }
        printf("\n");
    }
    int sum = 0;
    #pragma omp parallel for private(i, j)
        for (i = 0; i < i1; i++)
            for (j = 0; j < j1; j++){
                sum += matrixA[i][j];
           }


    printf("\nTHE RESULT IS: %d", sum);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并且,我想问一下,如果有更好的解决方案,因为我读到这是最有效的方法.

Zul*_*lan 5

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

sum += matrixA[i][j];
Run Code Online (Sandbox Code Playgroud)

当由多个线程并行执行时,将导致经典竞争条件.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)
Run Code Online (Sandbox Code Playgroud)

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

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