2010-02-28 8 views
9

Ich arbeite in C mit OpenMP mit gcc auf einem Linux-Rechner. In einem openmp parallel for-Schleife kann ich ein statisch zugewiesenes Array als privat deklarieren. Betrachten Sie das Codefragment:So stellen Sie sicher, dass ein dynamisch zugewiesenes Array in openmp privat ist

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

Und alles funktioniert wie erwartet. Aber wenn stattdessen zuweisen ich eine dynamisch,

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

die Werte von a (mindestens a [1 ... 9]) sind nicht geschützt, sondern handeln, als ob sie geteilt werden. Dies ist verständlich, da nichts im Pragma-Befehl omp sagt, wie groß das Array a ist, das privat sein muss. Wie kann ich diese Informationen an openmp weitergeben? Wie deklariere ich das gesamte dynamisch zugewiesene Array als privat?

Antwort

12

Ich glaube nicht, dass Sie tun - was ich getan habe, um dieses Problem zu lösen, wurde eine parallele Region #pragma omp parallel shared(...) private(...) verwendet und das Array dynamisch innerhalb der parallelen Region zugewiesen. Versuchen Sie folgendes:

#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]); 
    } 
} 

mir, dass die gleichen Ergebnisse wie meine früheren Versuchsprogramm erzeugt:

#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]); 
    } 
} 

Bei einer Vermutung würde ich sagen, weil OpenMP nicht die Größe des Arrays ableiten kann es kann Sei nicht privat - nur Arrays zur Kompilierungszeit können auf diese Weise erstellt werden. Ich erhalte Segfaults, wenn ich versuche, ein dynamisch zugewiesenes Array zu sperren, vermutlich wegen Zugriffsverletzungen. Das Array auf jedem Thread zuzuweisen, als ob Sie dies mit Pthreads geschrieben hätten, macht Sinn und löst das Problem.

+0

Danke, die Openmp-Deklaration und die Parallele zur Deklaration zu trennen scheint perfekt zu funktionieren. – cboettig

+0

@Ninefingers: Ich weiß, dass dieser Beitrag alt ist, aber ich hatte eine kurze Frage. Benötigen Sie überhaupt die Anweisung '#pragma omp for'? Würde es diese Schleife nicht parallel ausführen? – Amit

+1

@Amit nein, Sie müssen dem Compiler sagen, dass er Threads ausbrechen soll, sonst nicht. –

6

Sie haben OpenMP gesagt, dass der Zeigera privat ist, d. H. Repliziert in jedem Thread. Ihr Array ist nur ein paar beliebige Daten a Punkte zu, und OpenMP wird es nicht replizieren (vielleicht, weil dies die Zuordnung und die Zuordnung der replizierten Arrays erforderlich machen würde).

Verwandte Themen