Pergunta

I wrote following code. And I compiled and run the program. Segmentation fault occurred when calling mpif_set_si. But I can't understand why segmentation fault occur.

OS: Mac OS X 10.9.2 Compiler: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on 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;
}

-Command line-

$ 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
Foi útil?

Solução

private variables are not initialised, so they can have any value after the start of the parallel section. Initialising a value inside the parallel block can work, but often isn't efficient.

Usually a better way is to use firstprivate instead of private, which will initialise variables with the value they had before the parallel region.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top