/******************************************************************************
* Filename: 05reduction.c 
* Author:  Amy Apon
*
* Some simple timings and an example of reduction.
******************************************************************************/
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

#define LIMIT 1000000

int main (int argc, char *argv[]) {
int i, sum1, sum2, sum3a, sum3, mylimit, numthreads;
double start1, stop1, start2, stop2, start3, stop3;

  sum1=0;
  start1 = omp_get_wtime();
  for (i=0; i< LIMIT; i++)
  {
     sum1++;
  }
  stop1 = omp_get_wtime();

  
/* Fork a team of threads giving them their own copies of variables */
  sum2=0;
  start2 = omp_get_wtime();
#pragma omp parallel for reduction(+:sum2)
  for (i=0; i< LIMIT; i++)
  {
     sum2++;
  } /* All threads join master thread and disband */
  stop2 = omp_get_wtime();

  sum3=0;
  start3 = omp_get_wtime();
#pragma omp parallel shared(sum3)  private(mylimit, sum3a)
  {
    numthreads = omp_get_num_threads();
    /* This only works correctly when numthreads evenly divides LIMIT */
    mylimit = LIMIT/numthreads;
    sum3a=0;
    for (i=0; i<mylimit; i++)
      sum3a ++;
#pragma omp critical 
  {
     sum3 += sum3a;
  }
  } /* join all threads */
  stop3 = omp_get_wtime();
    

  /* Put all the output together at the end to avoid interfering with
     the timings. */
  printf("Sum1 = %d calculated in %lf seconds.\n", sum1, stop1-start1);
  printf("Sum2 = %d calculated in %lf seconds.\n", sum2, stop2-start2);
  printf("Sum3 = %d calculated in %lf seconds.\n", sum3, stop3-start3);

  return 0;
}


