mjee 0 Newbie Poster

I have written a program for the Game of Life in OpenMP with C. But the execution time is increasing with the number of threads.
Can you please help me with where I am wrong?

#include<stdio.h>
#include<stdlib.h>
#include <malloc.h>
#include <math.h>
#include <sys/time.h>
#include<omp.h>

#define ALIVE 1
#define DEAD 0

double gettime(void) {
  struct timeval tval;
  gettimeofday(&tval, NULL);
  return( (double)tval.tv_sec + (double)tval.tv_usec/1000000.0 );
}

void destroyArray(int **a, int P) {
  int i;
  for (i=0; i<P; i++)
    free(a[i]);
    free(a);
}

int **allocarray(int P, int Q) {
  int i;
  int **a;
  a = calloc(P,sizeof(int*));
  if (a == NULL) {
    printf("Error allocating memory\n");
    return 0;
    }
  /* for row major storage */
  for (i = 0; i < P; i++) {
    a[i] = calloc(Q,sizeof(int));
    if (a[i] == NULL) {
      destroyArray(a, i-1);
      return 0;
    }
  }
return a;
}

void initarray(int **array, int height, int width) {
  int i,j; 
  for (i=1; i<height-1; i++){
    for (j=1; j<width-1; j++){
      if(drand48()>0.5){
        array[i][j] = 1;
      }
      else{
        array[i][j] = 0;
      }
    }
  }
}

//print the table; currently not using it 
void printTable(int **table, int height, int width) {

                int h, w;
                for (h = 1; h < height-1; h++) {
                for (w = 1; w < width-1; w++) {
                        if (table[h][w] == ALIVE) {
                                printf(" X ");
                        } else {
                                printf(" 0 ");
                        }
                }
                printf("\n");
        }
        printf("\n");
}

//decide which neighbor is alive

int getNeighborValue(int **table, int row, int col) {
        if (table[row][col] == ALIVE) 
        { 
                return 1;
        } else {
                return 0;
        }
}

//number of neighbors alive

int getNeighborCount(int **table, int row, int col) {
        int neighbor = 0;

        neighbor += getNeighborValue(table, row - 1, col - 1);  //top left
        neighbor += getNeighborValue(table, row - 1, col);  //top
        neighbor += getNeighborValue(table, row - 1, col + 1);  //top right
        neighbor += getNeighborValue(table, row, col - 1);  //left
        neighbor += getNeighborValue(table, row, col + 1);  //right
        neighbor += getNeighborValue(table, row + 1, col - 1);  //below left
        neighbor += getNeighborValue(table, row + 1, col);   // below
        neighbor += getNeighborValue(table, row + 1, col + 1);  //below right
        
        return neighbor;
}

//calculating the status of the cell

int calculate(int **inputarray, int **outputarray, int height, int width) {
        int neighbor, h, w, flag=0;
        #pragma parallel for
        for (h = 1; h < height-1; h++) {
                for (w = 1; w < width-1; w++) {
                        neighbor = getNeighborCount(inputarray, h, w);
                        if (neighbor==3) {
                                outputarray[h][w] = ALIVE;
                        } else if (neighbor == 2 && inputarray[h][w] == ALIVE) {
                                outputarray[h][w] = ALIVE;
                        } else {
                                outputarray[h][w] = DEAD;
                        }
                         if(inputarray[h][w] != outputarray[h][w]){
                                flag= 1;
                        }
                }
        }
return flag;
}

int main(int argc, char *argv[]) {
        omp_set_nested(1);
        int generation = 0;
        int i;
        double starttime, endtime, time;
        int height,width;
        int flag = 0;
        int **array1, **array2, **temparray;

        if (argc!=3)
                printf("You need to enter the size of the matrix and the number of generations in the comment line argument\n");
        else
        {
                printf("The matrix size given is:%s * %s\n",argv[1], argv[1]);
                height = atoi(argv[1])+2;
                width  = height;
                array1 = allocarray(height, width);
                array2 = allocarray(height, width);
                if((array1 == 0) || (array2 == 0))
                {
                   printf("Allocation of one or both of the arrays failed!\n");
                   exit(1);
                }
                initarray(array1, height, width);
                printTable(array1, height, width);
                 starttime= gettime();
                //printf("Starttime= %f", starttime);
                for(i=0; i<(atoi(argv[2])); i++)
                {
                 #pragma omp parallel num_threads(1)
                flag = calculate(array1, array2, height, width);
                if (flag == 0)
                   break;
                printTable(array2, height, width);
                printf("Generation %d\n", ++generation);
                /* swap input and output arrays for next time through the loop: */
                temparray = array1;
                array1 = array2;
                array2 = temparray;
                }
        }
        endtime= gettime();
        //printf("Endtime= %f", endtime);
        time= (endtime-starttime);
        printf("Time taken= %1f\n", time); 
         
        return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.