问题
I am trying to add OpenMP parallelization to a working code (just to a single for
loop), however I cannot get rid of a segmentation fault. The problem arises from this line:
pos += sprintf(com + pos, "%d ", i);
com
is a character array, and I tried defining it as char com[255]
or char *com = malloc(255*sizeof(char))
, both inside and before the for
loop. I added private(com)
to #pragma omp parallel for
directive when I defined com
before the loop. I also tried initializing it and using firstprivate
. (pos
is an integer, initialized to 0
)
When I do not add -fopenmp
everything works fine, but with -fopenmp
it gives segfault. What am I missing?
回答1:
The segmentation fault comes from multiple threads updating the value of pos
at the same time, therefore setting it to some value that turns com + pos
into a pointer that points beyond or before the allocated memory for com
. The proper way to parallelise such a loop would be to concatenate the values in private strings and then concatenate the private strings in an ordered fashion:
char com[255];
int pos = 0;
#pragma omp parallel
{
char mycom[255];
int mypos = 0;
#pragma omp for schedule(static) nowait
for (int i = 0; i < N; i++)
mypos += sprintf(mycom + mypos, "%d ", i);
// Concatenate the strings in an ordered fashion
#pragma omp for schedule(static) ordered
for (int i = 0; i < omp_get_num_threads(); i++)
{
#pragma omp ordered
pos += sprintf(com + pos, "%s", mycom);
}
}
The ordered
construct ensures proper synchronisation so one does not need critical
. The use of schedule(static)
is important in order to guarantee each thread processes a single contiguous section of the iteration space.
来源:https://stackoverflow.com/questions/29247593/openmp-segfault