我正在尝试将OpenMP并行化添加到工作代码(仅限于单个for
循环),但是我无法摆脱分段错误。问题出在这一行:
pos += sprintf(com + pos, "%d ", i);
com
是一个字符数组,我尝试在char com[255]
循环内部和之前将其定义为char *com = malloc(255*sizeof(char))
或for
。当我在循环之前定义private(com)
时,我将#pragma omp parallel for
添加到com
指令。我也尝试初始化它并使用firstprivate
。 (pos
是一个整数,初始化为0
)
当我不添加-fopenmp
时,一切正常,但-fopenmp
会产生段错误。我错过了什么?
答案 0 :(得分:5)
分段错误来自多个线程同时更新pos
的值,因此将其设置为某个值,将com + pos
转换为指向{的分配内存之外或之前的指针{1}}。并行化这种循环的正确方法是将私有字符串中的值连接起来,然后以有序的方式连接私有字符串:
com
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);
}
}
构造确保正确同步,因此不需要ordered
。使用critical
非常重要,以保证每个线程处理迭代空间的单个连续部分。