Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.43 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <stdbool.h>
  5. #include <limits.h>
  6. #include <time.h>
  7. #include <math.h>
  8.  
  9.  
  10. struct Parameters {
  11. int left; // left end of the segment
  12. int right; // right end of the segment
  13. int size; // sqrt(n)
  14. int *max_printed_number; // the biggest right end of printed segment
  15. int *amount_of_working_threads; // amount of working threads
  16. bool *first_numbers; // prime-not prime boolean array on first sqrt(n) numbers
  17. };
  18.  
  19.  
  20. const int max_memory_size = 100000; // maximal memory for all threads
  21. const int limit = INT_MAX; // maximal number we are working with
  22. const int retries = 1; // amount of testing retrying for time counting
  23. pthread_attr_t attr;
  24.  
  25.  
  26. int min(int a, int b) {
  27. if (a < b) {
  28. return a;
  29. }
  30. return b;
  31. }
  32.  
  33.  
  34. int max(int a, int b) {
  35. if (a > b) {
  36. return a;
  37. }
  38. return b;
  39. }
  40.  
  41.  
  42. int integer_sqrt(int n) {
  43. return (int)ceil(sqrt(n));
  44. }
  45.  
  46.  
  47. int myCeil(int numerator, int denominator) {
  48. return (numerator - 1) / denominator + 1;
  49. }
  50.  
  51.  
  52. void * eratosphen_initialisation(bool* first_sqrt_numbers, int size) {
  53. for (int i = 0; i <= size; ++i) {
  54. first_sqrt_numbers[i] = true;
  55. }
  56. for (int i = 2; i <= size; ++i) {
  57. if (first_sqrt_numbers[i]) {
  58. for (int j = 2 * i; j <= size; j += i) {
  59. first_sqrt_numbers[j] = false;
  60. }
  61. }
  62. }
  63. for (int i = 2; i <= size; ++i) {
  64. if (first_sqrt_numbers[i]) {
  65. printf("%d\n", i);
  66. }
  67. }
  68. return NULL;
  69. }
  70.  
  71.  
  72.  
  73. void * eratosphen_iteration(void* vp) {
  74. printf("I entered the function\n");
  75. struct Parameters* p = (struct Parameters*)vp;
  76. int segment_size = p->right - p->left + 1;
  77. bool* new_segment = (bool*) malloc(sizeof(bool) * segment_size);
  78. // за число k отвечает индекс k - p->left;
  79. for (int i = 0; i < segment_size; ++i) {
  80. new_segment[i] = true;
  81. }
  82. int j = 0;
  83. printf("I'm in function\n");
  84. for (int i = 2; i <= p->size; ++i) {
  85. if (p->first_numbers[i]) {
  86. printf("%d is prime\n", i);
  87. j = myCeil(p->left, i) * i - p->left;
  88. for (; j < segment_size; j += i) {
  89. printf("%d is not prime\n", j);
  90. new_segment[j] = false;
  91. }
  92. }
  93. }
  94. while ((*(p->max_printed_number)) + 1 != p->left) {
  95. //wait
  96. }
  97. for (int i = 0; i < segment_size; ++i) {
  98. if (new_segment[i]) {
  99. printf("%d\n", i + p->left);
  100. }
  101. }
  102. free(new_segment);
  103. *(p->max_printed_number) = p->right;
  104. (*(p->amount_of_working_threads))--;
  105. return NULL;
  106. }
  107.  
  108. void eratosphenus(int threads_num, int n) {
  109. int max_printed_number = 0;
  110. int max_given_number = 0;
  111. int first_elements_amount = integer_sqrt(n);
  112. bool* first_numbers = (bool*) malloc(sizeof(bool) * (first_elements_amount + 1));
  113. printf("First elements amount -- %d\n", first_elements_amount);
  114. //sqrt(INT_MAX) = 2**16 = 65536 - is not really big, so I didn't parallelize this
  115. eratosphen_initialisation(first_numbers, first_elements_amount);
  116. max_given_number = first_elements_amount;
  117. max_printed_number = max_given_number;
  118. // Here our first sqrt(n) elements are ready
  119.  
  120. int max_thread_memory = myCeil(min(max_memory_size, n), threads_num);
  121. pthread_t *threads = (pthread_t *) malloc(sizeof(pthread_t) * threads_num);
  122. struct Parameters* parameters = (struct Parameters*) malloc(sizeof(struct Parameters)
  123. * threads_num);
  124. int amount_of_working_threads = 0;
  125. int next_max_given_number = 0;
  126. int next_free_thread = 0;
  127. pthread_attr_init(&attr);
  128. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  129. printf("max_given_number -- %d; max_printed_number -- %d\n", max_given_number, max_printed_number);
  130. printf("I am here\n");
  131. while (max_given_number < n) {
  132. if (amount_of_working_threads < threads_num) {
  133. next_max_given_number = min(max_given_number, n - max_thread_memory) + max_thread_memory;
  134. struct Parameters new_parameter = {max_given_number + 1, next_max_given_number, n,
  135. &max_printed_number, &amount_of_working_threads};
  136. parameters[next_free_thread % threads_num] = new_parameter;
  137. pthread_create(threads + (next_free_thread % threads_num), &attr,
  138. eratosphen_iteration, &parameters[next_free_thread % threads_num]);
  139. printf("Created from %d to %d\n", max_given_number + 1, next_max_given_number);
  140. amount_of_working_threads++;
  141. next_free_thread++;
  142. max_given_number = next_max_given_number;
  143. }
  144. }
  145. printf("I finished\n");
  146. free(first_numbers);
  147. free(parameters);
  148. free(threads);
  149. }
  150.  
  151.  
  152. int main(int argc, char** argv) {
  153. int n = 0;
  154. if (argc == 2) {
  155. n = limit;
  156. }
  157. else {
  158. n = atol(argv[2]);
  159. }
  160. int threads_num = atol(argv[1]);
  161. threads_num = min(threads_num, n); // No reason to have threads more than numbers
  162. //clock_t start, end;
  163. //start = clock();
  164. for (int i = 0; i < retries; ++i) {
  165. eratosphenus(threads_num, n);
  166. }
  167. //end = clock();
  168. //printf("%f seconds", (float)(end- start)/retries/CLOCKS_PER_SEC);
  169. return 0;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement