2010-02-28 5 views
9

Sto lavorando in C con openMP utilizzando gcc su una macchina Linux. In un ciclo parallelo in openmp, posso dichiarare un array allocato staticamente come privato. Considerare il frammento di codice:Come assicurarsi che una matrice allocata dinamicamente sia privata nella openmp

int a[10]; 
#pragma omp parallel for shared(none) firstprivate(a) 
for(i=0;i<4;i++){ 

E tutto funziona come previsto. Ma se invece mi allocare un modo dinamico,

int * a = (int *) malloc(10*sizeof(int)); 
#pragma omp parallel for shared(none) firstprivate(a) 

i valori di un (almeno [1 ... 9]) non sono protetti, ma si comportano come se sono condivisi. Questo è comprensibile dal momento che nulla nel comando pragma sembra dire a omp quanto è grande l'array a che deve essere privato. Come posso passare questa informazione a openmp? Come dichiaro l'intero array assegnato dinamicamente come privato?

risposta

12

Non penso che tu faccia - quello che ho fatto per risolvere questo problema è stato usato una regione parallela #pragma omp parallel shared(...) private(...) e assegnato l'array dinamicamente all'interno della regione parallela. Prova questo:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

/* compile with gcc -o test2 -fopenmp test2.c */ 

int main(int argc, char** argv) 
{ 
    int i = 0; 
    int size = 20; 
    int* a = (int*) calloc(size, sizeof(int)); 
    int* b = (int*) calloc(size, sizeof(int)); 
    int* c; 

    for (i = 0; i < size; i++) 
    { 
     a[i] = i; 
     b[i] = size-i; 
     printf("[BEFORE] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 

    #pragma omp parallel shared(a,b) private(c,i) 
    { 
     c = (int*) calloc(3, sizeof(int)); 

     #pragma omp for 
     for (i = 0; i < size; i++) 
     { 
      c[0] = 5*a[i]; 
      c[1] = 2*b[i]; 
      c[2] = -2*i; 
      a[i] = c[0]+c[1]+c[2]; 

      c[0] = 4*a[i]; 
      c[1] = -1*b[i]; 
      c[2] = i; 
      b[i] = c[0]+c[1]+c[2]; 
     } 

     free(c); 
    } 

    for (i = 0; i < size; i++) 
    { 
     printf("[AFTER] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 
} 

Questo per me ha prodotto gli stessi risultati come il mio precedente programma di esperimento:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

/* compile with gcc -o test1 -fopenmp test1.c */ 

int main(int argc, char** argv) 
{ 
    int i = 0; 
    int size = 20; 
    int* a = (int*) calloc(size, sizeof(int)); 
    int* b = (int*) calloc(size, sizeof(int)); 

    for (i = 0; i < size; i++) 
    { 
     a[i] = i; 
     b[i] = size-i; 
     printf("[BEFORE] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 

    #pragma omp parallel for shared(a,b) private(i) 
    for (i = 0; i < size; i++) 
    { 
     a[i] = 5*a[i]+2*b[i]-2*i; 
     b[i] = 4*a[i]-b[i]+i; 
    } 

    for (i = 0; i < size; i++) 
    { 
     printf("[AFTER] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 
} 

A occhio e croce direi perché OpenMP non può dedurre la dimensione della matrice si può essere privato - solo gli array in fase di compilazione possono essere eseguiti in questo modo. Ottengo segfaults quando provo a privare un array assegnato dinamicamente, presumibilmente a causa di violazioni di accesso. L'allocazione dell'array su ciascun thread come se avessi scritto questo utilizzando pthreads ha senso e risolve il problema.

+0

Grazie, separare la dichiarazione openmp e il parallelo per la dichiarazione sembra aver funzionato perfettamente. – cboettig

+0

@Ninefingers: so che questo post è vecchio, ma ho avuto una breve domanda. Hai addirittura bisogno dell'istruzione '#pragma omp for'? Non eseguirà quel ciclo in parallelo, indipendentemente? – Amit

+1

@Amit no, devi dire al compilatore di rompere i thread, altrimenti non lo farà. –

6

Hai detto a OpenMP che il puntatore a è privato, cioè replicato in ogni thread. Il tuo array è solo alcuni dati arbitrari a punti, e OpenMP non lo replicherà (forse perché questo renderebbe necessario allocare e deallocare gli array replicati).