Advertisement
Guest User

Untitled

a guest
Jan 21st, 2018
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.08 KB | None | 0 0
  1. #include <time.h>
  2. #include <omp.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <vector>
  6.  
  7. #define ANSI_COLOR_RESET "\x1b[0m"
  8. #define ANSI_COLOR_DEAD "\x1b[34m"
  9. #define ANSI_COLOR_POPULATION_1 "\x1b[31m"
  10. #define ANSI_COLOR_POPULATION_2 "\x1b[32m"
  11.  
  12. // na pełny ekran 1440x900 optymalny rozmiar to około 54x175
  13.  
  14. const int X = 54; // wiersze
  15. const int Y = 175; // kolumny
  16. const int CELL_COUNT = X * Y; //liczba komorek
  17.  
  18. const int ITERATION_COUNT = 200; //liczba iteracji - czas trwania symulacji
  19. const double TIME_INTERVAL = 0.75f; // in seconds (co ile ma iść następna iteracja)
  20.  
  21. const int DEAD_FIELD = 0, FIRST_POPULATION = 1, SECOND_POPULATION = 2;
  22.  
  23. char tab[2][X + 2][Y + 2];
  24.  
  25. void clearTable(char tab[2][X + 2][Y + 2], int layer);
  26. void initTable(char tab[2][X + 2][Y + 2], int layer, int percentage, int populationId);
  27. char setCellState(const char tab[2][X + 2][Y + 2], int row, int col, int whichLayer);
  28. void printTable(const char tab[2][X + 2][Y + 2], int whichLayer);
  29. void clear_screen();
  30.  
  31. int t1_currentRow, t2_currentRow;
  32. bool threadsMet = false; // Informuje czy wątki się spotkały (są w tym samym wierszu tablicy) w danej iteracji
  33.  
  34. int main()
  35. {
  36. omp_set_num_threads(2); //omp - ustawienie liczby wątkow
  37. srand((unsigned int)time(NULL));
  38. initTable(tab, 0, 50, FIRST_POPULATION);
  39. initTable(tab, 0, 50, SECOND_POPULATION);
  40. printf("Zmaksymalizuj ekran i nacisnij enter...");
  41. getchar();
  42. printTable(tab, 0);
  43.  
  44. double programTimestart = omp_get_wtime();
  45. double start = 0;
  46.  
  47. // #################################### MAIN LOOP ######################################
  48. //zagniezdzone rownoleglosci (rekurencyjne wywolywanie powoduje zwiekszenie sie watkow)
  49. //np. 4 razy wywolane z ustawionymi dwoma watkami na samym poczatku - 2^4=16
  50. omp_set_nested(true);
  51. //za pomoca omp_lock_t tworzymy zmienna do sekcji krytycznych (lock'ow)
  52. omp_lock_t lock;
  53. omp_init_lock(&lock);
  54. for (int t = 0; t < ITERATION_COUNT; t++) {
  55. clear_screen();
  56. start = omp_get_wtime();
  57.  
  58. while (true) // odczekaj TIME_INTERVAL
  59. if (omp_get_wtime() - start > TIME_INTERVAL) break;
  60.  
  61. //rozpoczecie rownleglosci.
  62. #pragma omp parallel
  63. {
  64. //przypisanie niezaleznych od siebie blokow kodu.
  65. #pragma omp sections
  66. {
  67. // Jeden wątek sprawdza komórki od góry...
  68. #pragma omp section
  69. {
  70. for (int i = 1; i <= X; i++) {
  71. t1_currentRow = i;
  72. for (int j = 1; j <= Y; j++)
  73. tab[(t + 1) % 2][i][j] = setCellState(tab, i, j, t % 2);
  74.  
  75. //sekcja krytyczna
  76. omp_set_lock(&lock);
  77. //sprawdza czy watki maja takie same zmienne t1.... i t2...
  78. #pragma omp flush(t1_currentRow, t2_currentRow)
  79. if (threadsMet) {
  80. omp_unset_lock(&lock);
  81. //koniec sekcji krytycznej
  82. break;
  83. }
  84. // Sprawdź czy wątki są na tym samym wierszu
  85. threadsMet = (t2_currentRow - t1_currentRow < 1 && t2_currentRow - t1_currentRow >= 0);
  86. omp_unset_lock(&lock);
  87. } // for (int i = 1; i <= X; i++)
  88. } // #pragma omp section
  89.  
  90. // ...a drugi od dołu
  91. #pragma omp section
  92. {
  93. for (int k = X; k >= 1; k--) {
  94. t2_currentRow = k;
  95. for (int l = Y; l >= 1; l--)
  96. tab[(t + 1) % 2][k][l] = setCellState(tab, k, l, t % 2);
  97.  
  98. omp_set_lock(&lock);
  99. #pragma omp flush(t1_currentRow, t2_currentRow)
  100. if (threadsMet) {
  101. omp_unset_lock(&lock);
  102. break;
  103. }
  104. // sprawdz czy wątki są na tym samym wierszu
  105. if ((t2_currentRow - t1_currentRow) == 0)
  106. threadsMet = true;
  107. omp_unset_lock(&lock);
  108. } // for (int k = X ; k >= 1; k--)
  109. } // #pragma omp section
  110. } // #pragra omp sections
  111. } // #pragma omp parallel
  112. threadsMet = false;
  113. t2_currentRow = X;
  114. t1_currentRow = 1;
  115.  
  116. printTable(tab, (t + 1) % 2);
  117. } // for (int t = 0; t < ITERATION_COUNT; t++)
  118. // #################################### MAIN LOOP ###################################### END
  119.  
  120. double programTimestop = omp_get_wtime();
  121. printf("Elapsed time: %f\n", programTimestop - programTimestart);
  122.  
  123. omp_destroy_lock(&lock);
  124. return EXIT_SUCCESS;
  125. }
  126.  
  127.  
  128. void clear_screen() {
  129. printf("\033[H\033[J");
  130. }
  131.  
  132. void initTable(char tab[2][X + 2][Y + 2], int layer, int percentage, int population)
  133. {
  134. for (int i = 1; i < X; i++)
  135. for (int j = 1; j < Y; j++)
  136. if ((rand() % percentage) == (percentage-1)) // zamiast 9 może być dowolona liczba od 0 do percentage - 1
  137. tab[layer][i][j] = population;
  138. }
  139.  
  140. char setCellState(const char tab[2][X + 2][Y + 2], int row, int col, int layer)
  141. {
  142. std::vector<int> populationCount(SECOND_POPULATION + 1, 0);
  143. populationCount[tab[layer][row - 1][col]]++;
  144. populationCount[tab[layer][row - 1][col + 1]]++;
  145. populationCount[tab[layer][row][col - 1]]++;
  146. populationCount[tab[layer][row][col + 1]]++;
  147. populationCount[tab[layer][row + 1][col - 1]]++;
  148. populationCount[tab[layer][row + 1][col]]++;
  149. populationCount[tab[layer][row + 1][col + 1]]++;
  150. populationCount[tab[layer][row - 1][col - 1]]++;
  151.  
  152. bool population1Lives = (populationCount[FIRST_POPULATION] == 2 || populationCount[FIRST_POPULATION] == 3);
  153. bool population2Lives = (populationCount[SECOND_POPULATION] == 2 || populationCount[SECOND_POPULATION] == 3);
  154. int randomFactor = rand() % 2 + 1;
  155.  
  156. return (!population1Lives && !population2Lives) ? DEAD_FIELD :
  157. (population1Lives && !population2Lives) ? FIRST_POPULATION :
  158. (!population1Lives && population2Lives) ? SECOND_POPULATION :
  159. (randomFactor == 0) ? FIRST_POPULATION : SECOND_POPULATION;
  160. }
  161.  
  162. void printTable(const char tab[2][X + 2][Y + 2], int layer)
  163. {
  164. for (int i = 1; i <= X; i++) {
  165. for (int j = 1; j <= Y; j++) {
  166. switch (tab[layer][i][j])
  167. {
  168. case FIRST_POPULATION:
  169. printf(ANSI_COLOR_POPULATION_1 "x" ANSI_COLOR_RESET);
  170. break;
  171. case SECOND_POPULATION:
  172. printf(ANSI_COLOR_POPULATION_2 "x" ANSI_COLOR_RESET);
  173. break;
  174. default:
  175. printf(ANSI_COLOR_DEAD "o" ANSI_COLOR_RESET);
  176. break;
  177. }
  178. }
  179. printf("\n");
  180. }
  181. }
  182.  
  183. void clearTable(char tab[2][X + 2][Y + 2], int layer)
  184. {
  185. for (int i = 1; i < X; i++)
  186. for (int j = 1; j < Y; j++)
  187. tab[layer][i][j] = DEAD_FIELD;
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement