2016-11-26 93 views
2

我已经写了这个代码读取矩阵,它基本上总结了矩阵的值...但是我的问题是,因为我尝试以不同的方式执行杂注,我发现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; 
} 

而且,我想问一下,是否会有像,有关编译还原一个更好的解决方案,因为我读的是最有效的方法。

+0

您应该同时放置缩减和'sum + = ..',因为您希望单个OpenMP线程执行'sum + = ...',并减少每个OpenMP thead的总和变量。 – yakoudbz

+0

如果我理解你的效率是什么意思,那么即使需要单独命名的内部和外部还原变量,也希望在每个线程内减少simd以及外部循环缩减。 – tim18

回答

5

您发布的代码是不减少条款不正确。当通过并联多个线程执行

sum += matrixA[i][j]; 

会导致经典竞争状态。总和是一个共享变量,但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 += ...标记为原子操作或临界区。然而,这具有显着的性能损失。

相关问题