HotbrewGX
HotbrewGX

Reputation: 11

Need explanation on why my pi is equal to 0

I was rewriting the code below using OpenMP task to parallilize the Pi program.

Original Code:

#include <omp.h>
#include <stdio.h>
static long num_steps = 1024*1024*1024;
#define MIN_BLK  1024*1024*256

double pi_comp(int Nstart,int Nfinish,double step)
{  int i,iblk;
double x, sum = 0.0,sum1, sum2;
if (Nfinish-Nstart < MIN_BLK){
  for (i=Nstart;i< Nfinish; i++){
     x = (i+0.5)*step;
     sum = sum + 4.0/(1.0+x*x); 
  }
}
else{
  iblk = Nfinish-Nstart;
  sum1 = pi_comp(Nstart,         Nfinish-iblk/2,step);
  sum2 = pi_comp(Nfinish-iblk/2, Nfinish,       step);
  sum = sum1 + sum2;
}return sum;
}
int main ()
{
int i;
double step, pi, sum;
double init_time, final_time;
step = 1.0/(double) num_steps;

init_time = omp_get_wtime();
sum = pi_comp(0,num_steps,step);
pi = step * sum;
final_time = omp_get_wtime() - init_time;
printf(" for %ld steps pi = %f in %f secs\n",num_steps,pi,final_time);

}  

OpenMP Code:

#include <omp.h>
#include <stdio.h>
static long num_steps = 1024*1024*1024;
#define MIN_BLK  1024*1024*256

double pi_comp(int Nstart,int Nfinish,double step)
{  int i,iblk;
double x, sum = 0.0,sum1, sum2;
if (Nfinish-Nstart < MIN_BLK){
  for (i=Nstart;i< Nfinish; i++){
     x = (i+0.5)*step;
     sum = sum + 4.0/(1.0+x*x); 
  }
}
else{
  iblk = Nfinish-Nstart;
  #pragma omp task firstprivate(sum1)
  sum1 = pi_comp(Nstart,Nfinish-iblk/2,step);
  #pragma omp task firstprivate(sum2)
  sum2 = pi_comp(Nfinish-iblk/2, Nfinish,step);
  sum = sum1 + sum2;
}return sum;
}
int main ()
{
int i;
double step, pi, sum;
double init_time, final_time;
step = 1.0/(double) num_steps;

init_time = omp_get_wtime();
#pragma omp parallel
{
#pragma omp single
sum = pi_comp(0,num_steps,step);
}

pi = step * sum;
final_time = omp_get_wtime() - init_time;
printf(" for %ld steps pi = %f in %f secs\n",num_steps,pi,final_time);

}  

I dont know why the output for the OpenMP program has pi = 0 instead of pi itself when testing the speed of a certain amount of thread. Is there something I did wrong in the OpenMP code that didn't give me pi?

Output:

g++ -fopenmp  -c pi_recur_omp.cpp
g++ -fopenmp  -o pi_recur_omp pi_recur_omp.o -lm
./pi_recur 
 for 1073741824 steps pi = 3.141593 in 4.562793 secs
./pi_recur_omp 
 for 1073741824 steps pi = 0.000000 in 2.990318 secs

Upvotes: 0

Views: 84

Answers (2)

Laci
Laci

Reputation: 2818

Your OpenMP code is not working properly because of:

  1. sum1 and sum2 should be shared. Using the firstprivate clause (which is the default) makes them private, so the updated values are not available outside the tasks.
  2. You have to wait for tasks to finish before you can sum them, so a #pragma omp taskwait line is needed.

So, your code can be corrected using:

#pragma omp task shared(sum1)
sum1 = pi_comp(Nstart,Nfinish-iblk/2,step);
#pragma omp task shared(sum2)
sum2 = pi_comp(Nfinish-iblk/2, Nfinish,step);
#pragma omp taskwait
sum = sum1 + sum2;

As pointed out by @JerryCoffin a simple iterative method gives much better performance compared to your recursive code using tasks.

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490663

In this case, I'd say the mistake is using recursion at all. It doesn't really gain you much (if anything at all). I'd probably just do a simple iterative version:

#include <omp.h>
#include <stdio.h>
static long num_steps = 1024*1024*1024;

double pi_comp(int Nstart,int Nfinish,double step)
{  
    int i,iblk;
    double sum = 0.0,sum1, sum2;

#pragma omp parallel for reduction(+:sum)
    for (i=Nstart;i< Nfinish; i++){
        double x = (i+0.5)*step;
        sum = sum + 4.0/(1.0+x*x); 
    }
    return sum;
}
int main ()
{
    int i;
    double step, pi, sum;
    double init_time, final_time;
    step = 1.0/(double) num_steps;

    init_time = omp_get_wtime();
    sum = pi_comp(0,num_steps,step);
    pi = step * sum;
    final_time = omp_get_wtime() - init_time;
    printf(" for %ld steps pi = %f in %f secs\n",num_steps,pi,final_time);

}

Result:

for 1073741824 steps pi = 3.141593 in 0.455449 secs

Upvotes: 1

Related Questions