Advertisement
Guest User

t2.c

a guest
Jun 24th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.63 KB | None | 0 0
  1. /*
  2. * The Game of Life
  3. *
  4. * a cell is born, if it has exactly three neighbours
  5. * a cell dies of loneliness, if it has less than two neighbours
  6. * a cell dies of overcrowding, if it has more than three neighbours
  7. * a cell survives to the next generation, if it does not die of loneliness
  8. * or overcrowding
  9. *
  10. * In this version, a 2D array of ints is used.  A 1 cell is on, a 0 cell is off.
  11. * The game plays a number of steps (given by the input), printing to the screen each time.  'x' printed
  12. * means on, space means off.
  13. *
  14. */
  15. #include <pthread.h>
  16. #include <semaphore.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20. #include <sys/sysinfo.h>
  21. #include <unistd.h>
  22. #include <mpi.h>
  23.  
  24. typedef unsigned char cell_t;
  25.  
  26. /* ------------------------------------------------------------------------- */
  27.  
  28. cell_t ** allocate_board (int size) {
  29.   cell_t ** board = (cell_t **) malloc(sizeof(cell_t*)*size);
  30.   int   i;
  31.   for (i=0; i<size; i++)
  32.   board[i] = (cell_t *) malloc(sizeof(cell_t)*size);
  33.   return board;
  34. }
  35.  
  36. /* ------------------------------------------------------------------------- */
  37.  
  38. void free_board (cell_t ** board, int size) {
  39.   int     i;
  40.   for (i=0; i<size; i++)
  41.   free(board[i]);
  42.   free(board);
  43. }
  44.  
  45. /* ------------------------------------------------------------------------- */
  46.  
  47. /* return the number of on cells adjacent to the i,j cell */
  48.  int adjacent_to (cell_t ** board, int size, int i, int j) {
  49.   int count = 0;
  50.   count+=board[i-1][j-1];
  51.   count+=board[i-1][j];
  52.   count+=board[i-1][j+1];
  53.   count+=board[i][j-1];
  54.   count+=board[i][j+1];
  55.   count+=board[i+1][j-1];
  56.   count+=board[i+1][j];
  57.   count+=board[i+1][j+1];
  58.   return count;
  59. }
  60.  
  61. /* ------------------------------------------------------------------------- */
  62.  
  63. /* print the life board */
  64. void print (cell_t ** board, int size) {
  65.   int   i, j;
  66.   /* for each row */
  67.   for (j=1; j<size+1; j++) {
  68.     /* print each column position... */
  69.     for (i=1; i<size+1; i++)
  70.       if(board[i][j]){
  71.           printf ("■ ");
  72.       } else {
  73.         printf ("  ");
  74.       }
  75.     /* followed by a carriage return */
  76.     printf ("\n");
  77.   }
  78. }
  79.  
  80. /* ------------------------------------------------------------------------- */
  81.  
  82. /* read a file into the life board */
  83. void read_file (FILE * f, cell_t ** board, int size) {
  84.   int   i, j;
  85.   char  *s = (char *) malloc(size+10);
  86.  
  87.   /* read the first new line (it will be ignored) */
  88.   fgets (s, size+10,f);
  89.  
  90.   /* read the life board */
  91.   for (j=0; j<size; j++) {
  92.     /* get a string */
  93.     fgets (s, size+10,f);
  94.     /* copy the string to the life board */
  95.     for (i=0; i<size; i++)
  96.     board[i+1][j+1] = s[i] == 'x';
  97.   }
  98.   for (i=0; j<size+2; i++) {
  99.     board[0][j] = 0;
  100.     board[j][size+1] = 0;
  101.     board[size+1][j] = 0;
  102.     board[j][size+1] = 0;
  103.   }
  104.  
  105. }
  106.  
  107. void fill_board(cell_t ** board, int size, int percentage_alive) {
  108.   int   i, j;
  109.   srand(time(NULL));
  110.   for (j=1; j<size+1; j++) {
  111.     for (i=1; i<size+1; i++){
  112.         board[i][j] = ((int)(rand()) %percentage_alive == 0? 1 : 0 );
  113.     }
  114.   }
  115. }
  116.  
  117.  
  118.  void get_next_state(cell_t** board, cell_t** newboard, int a, int i, int j){
  119.   if (a == 2) {
  120.     newboard[i][j] = board[i][j];
  121.   } else if (a == 3) {
  122.     newboard[i][j] = 1 ;
  123.   } else {
  124.     newboard[i][j] = 0;
  125.   }
  126. }
  127.  
  128. /* ------------------------------------------------------------------------- */
  129.  
  130. int main(int argc, char**argv){
  131. int size, steps;
  132.   cell_t ** board;
  133.   cell_t ** newboard;
  134.   //if (argc<2 || atoi(argv[1])){
  135.     FILE    *f;
  136.     f = stdin;
  137.     fscanf(f,"%d %d", &size, &steps);
  138.     board = allocate_board (size+2);
  139.     read_file (f, board,size);
  140.     fclose(f);
  141.     newboard = allocate_board (size+2);
  142.   /*} else {
  143.     steps = 1000;
  144.     size = 1000;
  145.     board = allocate_board (size+2);
  146.     newboard = allocate_board (size+2);
  147.     fill_board(board, size, 32);
  148.   }
  149.   /**/
  150.   cell_t ** tmp;
  151.   int i;
  152.   #ifdef DEBUG
  153.     printf("Initial:\n");
  154.     //print(board,size);
  155.   #endif
  156.    printf ("You have %d processors.\n", get_nprocs());
  157.   int nthreads = atoi(argv[1]);
  158.  
  159.   MPI_Init(&argc, &argv);
  160.   //cria os processos
  161.   // for (int j = 0; j<nthreads; j++) {
  162.   //   if (fork() == 0){//se for um processo novo nao cria outros, quem faz isso é o principal
  163.   //     break;
  164.   //   }
  165.   // }
  166.  
  167.   int rank;
  168.   MPI_Comm_rank( MPI_COMM_WORLD, &rank);
  169.   //como o  rank 0 é o processo principal, os ranks começam do 1 o thread_number é o rank-1
  170.   int thread_number = rank-1;
  171.   //se for o processo inicial, não faz os calculos, apenas aguarda finalizarem
  172.   if (thread_number != 0){
  173.     for (i=0; i<steps; i++) {
  174.       int i, j;
  175.       /* for each cell, apply the rules of Life */
  176.       int maxi = (int)(size/(double)nthreads*(thread_number+1));
  177.       int mini = (int)(size/(double)nthreads*thread_number);
  178.       for (int k=0; k<steps; k++) {
  179.         // calcula a primeira e ultima linhas
  180.         for (j= 1; j<size+1; j++) {
  181.           get_next_state(board, newboard, adjacent_to(board, size, mini+1, j), mini+1, j);
  182.           get_next_state(board, newboard, adjacent_to(board, size, maxi+1, j), maxi+1, j);
  183.         }
  184.         // se não for a primeira seção, manda a primeira linha para o proc anterior
  185.         if (rank > 1){
  186.           MPI_Send(newboard[mini], size, MPI_CHAR, rank - 1, 0, MPI_COMM_WORLD);
  187.         }
  188.         if (rank < nthreads){
  189.           MPI_Send(newboard[maxi], size, MPI_CHAR, rank + 1, 0, MPI_COMM_WORLD);
  190.         }
  191.         //calcula o resto
  192.         for (i = mini+1 + 1; i<maxi+1-1; ++i) {
  193.           for (j= 1; j<size+1; j++) {
  194.             get_next_state(board, newboard, adjacent_to(board, size, i, j), i, j);
  195.           }
  196.         }
  197.         // recebe as novas linhas calculadas pelo outro processo
  198.         if (rank > 1){
  199.           MPI_Recv(newboard[mini], size, MPI_CHAR, rank-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  200.         }
  201.         if (rank < nthreads){
  202.           MPI_Recv(newboard[maxi+2], size, MPI_CHAR, rank+1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  203.         }
  204.         tmp = newboard;
  205.         newboard = board;
  206.         board = tmp;
  207.       }
  208.  
  209.       //manda suas linhas para o processo principal
  210.       for (int i = mini+1; i<maxi+1; ++i) {
  211.         //usando i como tag para receber na ordem certa
  212.         MPI_Send(newboard[i], size, MPI_CHAR, 0, i, MPI_COMM_WORLD);
  213.       }
  214.     }
  215.   } else {
  216.     //recebe os valores finais dos processos
  217.     for (int i = 1; i<size+1; ++i) {
  218.       MPI_Recv(newboard[i], size, MPI_CHAR, MPI_ANY_SOURCE, i, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  219.     }
  220.       #ifdef RESULT
  221.         printf("Final:\n");
  222.         //print (board,size);
  223.       #endif
  224.   }
  225.   free_board(newboard,size);
  226.   free_board(board,size);
  227.   MPI_Finalize();
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement