2016-11-26 2 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

Если я понимаю, что вы подразумеваете под эффективностью, вы бы хотели, чтобы уменьшение числа символов в каждом потоке, а также сокращение внешнего цикла, даже если для этого требуются отдельные внутренние и внешние переменные сокращения. – 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 += ... как атомной операции или критической секции. Это, однако, имеет значительный штраф в исполнении.

Смежные вопросы