2010-02-28 8 views
9

Estoy trabajando en C con openMP usando gcc en una máquina Linux. En un bucle de openmp paralelo para, puedo declarar una matriz estáticamente asignada como privada. Considere el fragmento de código:Cómo asegurar que una matriz dinámicamente asignada sea privada en openmp

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

Y todo funciona como se esperaba. Pero si en lugar asigno una forma dinámica,

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

los valores de una (al menos un [1 ... 9]) no están protegidos, pero actúan como si se comparten. Esto es comprensible ya que nada en el comando pragma parece indicar omp qué tan grande es la matriz a que debe ser privada. ¿Cómo puedo pasar esta información a openmp? ¿Cómo declaro que toda la matriz dinámicamente asignada es privada?

Respuesta

12

No creo que lo haga - lo que hice para resolver este problema fue utilizar una región paralela #pragma omp parallel shared(...) private(...) y asigné la matriz dinámicamente dentro de la región paralela. Prueba esto:

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

Eso me produjo los mismos resultados que mi anterior programa de experimento:

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

En una estimación diría porque OpenMP no puede deducir el tamaño de la matriz que puede no es privado; solo se pueden hacer arreglos en tiempo de compilación de esta manera. Obtengo segfaults cuando trato de mantener privada una matriz dinámicamente asignada, presumiblemente debido a violaciones de acceso. Asignar la matriz en cada hilo como si hubiera escrito esto usando pthreads tiene sentido y resuelve el problema.

+0

Gracias, separar la declaración de openmp y el paralelo para la declaración parece haber funcionado perfectamente. – cboettig

+0

@Ninefingers: Sé que esta publicación es antigua, pero tuve una pregunta rápida. ¿Necesitas siquiera la declaración '#pragma omp for'? ¿No realizaría ese ciclo en paralelo independientemente? – Amit

+1

@Amit no, necesitas decirle al compilador que sepa los hilos, de lo contrario no lo hará. –

6

Le dijo a OpenMP que el punteroa es privado, es decir, se replica en cada hilo. Su matriz es solo algunos datos arbitrarios a apunta a, y OpenMP no lo replicará (tal vez porque esto haría necesario asignar y desasignar las matrices replicadas).

Cuestiones relacionadas