Advertisement
Guest User

Untitled

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