2010-02-28 4 views
9

Я работаю в C с openMP, используя gcc на Linux-машине. В параллельной петле openmp я могу объявить статически выделенный массив как закрытый. Рассмотрим фрагмент кода:Как обеспечить динамически выделенный массив является private в openmp

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

И все работает должным образом. Но если вместо этого я выделяю динамически,

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

значения а (по крайней мере [1 ... 9]) не защищены, но действуют, как будто они являются общими. Это понятно, поскольку ничто в команде pragma не указывает omp, насколько велик массив a, который должен быть закрытым. Как передать эту информацию в openmp? Как объявить весь динамически выделенный массив как закрытый?

ответ

12

Я не думаю, что вы сделали - то, что я сделал для решения этой проблемы, было использовано в параллельной области #pragma omp parallel shared(...) private(...) и динамически распределяло массив внутри параллельной области. Попробуйте это:

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

Что мне произвел те же результаты, что и моей предыдущей программе эксперимента:

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

В догадке я бы сказал, потому что OpenMP не может вывести размер массива возможное 't быть приватным - только массивы времени компиляции могут быть выполнены таким образом. Я получаю segfaults, когда пытаюсь приватизировать динамически выделенный массив, предположительно из-за нарушений доступа. Выделение массива в каждом потоке, как если бы вы написали это с помощью pthreads, имеет смысл и решает проблему.

+0

Спасибо, отделив объявление openmp и объявление для объявления, похоже, отлично работали. – cboettig

+0

@Ninefingers: Я знаю, что этот пост старый, но у меня был быстрый вопрос. Вам вообще нужен оператор '#pragma omp for'? Разве он не будет выполнять этот цикл параллельно? – Amit

+1

@ Не говорите, вам нужно сказать компилятору, чтобы он вырвал потоки, иначе он не будет. – 2012-06-09 16:23:40

6

Вы сказали OpenMP, что указатель a является закрытым, то есть реплицируется в каждом потоке. Ваш массив - это всего лишь некоторые произвольные данные a, и OpenMP не будет реплицировать его (возможно, потому, что это потребовало бы выделения и освобождения реплицированных массивов).