如何确保动态分配的数组在openmp中是私有的

我在Linux机器上使用gcc使用openMP在C中工作。 在openmp并行for循环中,我可以将静态分配的数组声明为private。 考虑代码片段:

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) 

a(至少a [1 … 9])的值不受保护,但就好像它们是共享的一样。 这是可以理解的,因为pragma命令中的任何内容似乎都没有告诉omp数组a需要私有多大。 如何将此信息传递给openmp? 如何将整个动态分配的数组声明为私有?

我不认为你这样做 – 我用来解决这个问题的方法是使用并行区域#pragma omp parallel shared(...) private(...)并在并行区域内动态分配数组。 试试这个:

 #include  #include  #include  /* 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  #include  #include  /* 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不能推断出它不能是私有的数组的大小 - 只有编译时数组可以通过这种方式完成。 当我尝试私有动态分配的数组时,我得到段错误,可能是因为访问冲突。 在每个线程上分配数组就像使用pthreads编写它一样有意义并解决了这个问题。

你告诉OpenMP 指针 a是私有的,即在每个线程中复制。 您的数组只是一些指向的任意数据,OpenMP不会复制它(可能因为这将使得必须分配和释放复制的数组)。