How to ensure a dynamically allocated array is private in openmp
I'm working in C with openMP using gcc on a linux machine. In an openmp parallel for loop, I can declare a statically allocated array as private. Consider the开发者_运维技巧 code fragment:
int a[10];
#pragma omp parallel for shared(none) firstprivate(a)
for(i=0;i<4;i++){
And everything works as expected. But if instead I allocate a dynamically,
int * a = (int *) malloc(10*sizeof(int));
#pragma omp parallel for shared(none) firstprivate(a)
the values of a (at least a[1...9]) are not protected but act as if they are shared. This is understandable as nothing in the pragma command seems to tell omp how big the array a is that needs to be private. How can I pass this information to openmp? How do I declare the entire the dynamically allocated array as private?
I don't think you do - what I did to solve this problem was used a parallel region #pragma omp parallel shared(...) private(...)
and allocated the array dynamically inside the parallel region. Try this:
#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]);
}
}
That to me produced the same results as my earlier experiment program:
#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]);
}
}
At a guess I'd say because OpenMP can't deduce the size of the array it can't be private - only compile-time arrays can be done this way. I get segfaults when I try to private a dynamically allocated array, presumably because of access violations. Allocating the array on each thread as if you'd written this using pthreads makes sense and solves the issue.
You told OpenMP that the pointer a
is private, i.e. replicated in each thread. Your array is just some arbitrary data a
points to, and OpenMP will not replicate it (perhaps because this would make it necessary to allocate and deallocate the replicated arrays).
精彩评论