我写了以下代码。我编译并运行该程序。调用mpif_set_si时发生分段错误。但我无法理解为什么会发生分段错误。
操作系统:Mac OS X 10.9.2 编译器:i686-apple-darwin11-llvm-gcc-4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2336.11.00)
#include <stdio.h>
#include <gmp.h>
#include <math.h>
#define NUM_ITTR 1000000
int
main(void)
{
unsigned long int i, begin, end , perTh;
mpf_t pi, gbQuaterPi, quaterPi, pw, tmp;
int tn, nt;
mpf_init(quaterPi);
mpf_init(gbQuaterPi);
mpf_init(pw);
mpf_init(tmp);
mpf_init(pi);
#pragma omp parallel private(tmp, pw, quaterPi, tn, begin, end, i)
{
#ifdef OMP
tn = omp_get_thread_num();
nt = omp_get_num_threads();
perTh = NUM_ITTR / nt;
begin = perTh * tn;
end = begin + perTh - 1;
#else
begin = 0;
end = NUM_ITTR - 1;
#endif
for(i=begin;i<=end;i++){
printf("Before set begin=%lu %lu tn= %d\n", begin, end, tn);
mpf_set_si(tmp, -1); // segmentation fault occur
printf("After set begin=%lu %lu tn= %d\n", begin, end, tn);
mpf_pow_ui(pw, tmp, i);
mpf_set_si(tmp, 2);
mpf_mul_ui(tmp, tmp, i);
mpf_add_ui(tmp, tmp, 1);
mpf_div(tmp, pw, tmp);
mpf_add(quaterPi, quaterPi, tmp);
}
#pragma omp critical
{
mpf_add(gbQuaterPi, gbQuaterPi, quaterPi);
}
}
mpf_mul_ui(pi, gbQuaterPi, 4);
gmp_printf("pi= %.30ZFf\n", pi);
mpf_clear(pi);
mpf_clear(tmp);
mpf_clear(pw);
mpf_clear(quaterPi);
mpf_clear(gbQuaterPi);
return 0;
}
- 命令行 -
$ setenv OMP_NUM_THREADS 2
$ gcc -g -DOMP -I/opt/local/include -fopenmp -o calcpi calcpi.c -lgmp -L/opt/local/lib
$ ./calcpi
Before set begin=0 499999 tn= 0
Before set begin=500000 999999 tn= 1
After set begin=1 999999 tn= 1
Segmentation fault
答案 0 :(得分:0)
private
变量未初始化,因此它们可以在并行部分开始后具有任何值。在并行块内初始化值可以起作用,但通常效率不高。
通常更好的方法是使用firstprivate
代替private
,这将使用在并行区域之前的值初始化变量。