Advertisement
Briotar

Untitled

Apr 27th, 2021
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.84 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <signal.h>
  6. #include <pthread.h>
  7. #include <sched.h>
  8. #include <math.h>
  9. #include <sys/time.h>
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12.  
  13. typedef struct
  14. {
  15. pthread_t tid;
  16. int first;
  17. int last;
  18. } ThreadRecord;
  19.  
  20. ThreadRecord *threads;
  21.  
  22. double *vec_next ; //массив элементов в следующий момент времени
  23. double *vec ; //массив элементов в текущий момент времени
  24. double *p ;
  25.  
  26. pthread_barrier_t barr1, barr2;
  27.  
  28. struct timeval tv1,tv2,dtv;
  29. struct timezone tz;
  30.  
  31. double PI = 3.1415926535; //пи
  32. double R = 1000; //сопротивление
  33. double C = 1e-4; //ёмкость
  34. double IA = 2 ; //амплитуда силы тока
  35. int done = 0; //признак выполнения
  36. int time_moment = 0; //момент времени
  37. int num_of_elements = 100; //количество элементов(по умолчанию)
  38. int num_of_threads = 8; //количество потоков(по умолчанию)
  39. int time_intervals = 20 ; //количество временных интервалов(по умолчанию)
  40. double step ; //временной шаг
  41.  
  42. void print_nodes(double *vec_next, FILE **gp)
  43. { //визуализация работы
  44. int j ;
  45. //fprintf (*gp, "plot [0:%d][0:%lf]'-' with line title 'sin(x %+#.3g)'\n",num_of_elements,IA*R + 10 , -j*0.1);
  46. for ( j = 0 ; j < num_of_elements; j ++)
  47. {
  48. fprintf (*gp, " %# -15g\n", vec_next[ j]);
  49. }
  50. fprintf (*gp, "\n\n"); fflush (*gp); usleep (10000);
  51. }
  52.  
  53. void * node_method(void *arg_p)
  54. { //вычисление в узлах явным методом Эйлера
  55. int i ;
  56. ThreadRecord *thr;
  57. thr = (ThreadRecord *)arg_p;
  58. while(!done)
  59. {
  60. pthread_barrier_wait(&barr1);
  61. for ( i = thr->first; i < thr->last; i ++)
  62. {
  63. if(i && (i < num_of_elements - 1 ) &&(time_moment + 1 < (int)((double)time_intervals/step) ))
  64. {
  65. vec_next[ i] = vec[i] + step*(vec[ i - 1] - 2 * vec[i] + vec[i + 1])/(R*C);
  66. }
  67. }
  68. pthread_barrier_wait(&barr2);
  69. }
  70. }
  71.  
  72. int main(int argc, char *argv[], char *env[])
  73. {
  74. step = R*C/10;
  75. FILE *gp = fopen("data_test.txt", "w"); //файл для визуализации
  76. int i, j;
  77. if(argc >= 4)
  78. { //получение данных из командной строки
  79. num_of_elements = atoi(argv[1]);
  80. num_of_threads = atoi(argv[2]);
  81. time_intervals = atoi(argv[3]);
  82. if(num_of_elements < num_of_threads)
  83. num_of_threads = num_of_elements;
  84. }
  85. vec_next = (double *)malloc( num_of_elements * sizeof(double ));
  86. vec = (double *)malloc(num_of_elements * sizeof(double ));
  87. for ( i = 0; i < num_of_elements; i ++)
  88. {
  89. vec[i] = 0 ;
  90. }
  91. pthread_attr_t pattr;
  92. pthread_attr_init (&pattr);
  93. pthread_attr_setscope (&pattr, PTHREAD_SCOPE_SYSTEM);
  94. pthread_attr_setdetachstate (&pattr,PTHREAD_CREATE_JOINABLE);
  95. threads = (ThreadRecord *)malloc(num_of_threads * sizeof(ThreadRecord));
  96. pthread_barrier_init(&barr1, NULL, num_of_threads + 1);
  97. pthread_barrier_init(&barr2, NULL, num_of_threads + 1);
  98. int d = (num_of_elements%num_of_threads) ? 1 : 0 ;
  99. int len = num_of_elements/num_of_threads + d ;
  100. gettimeofday(&tv1, &tz);
  101. for ( i = 0; i < num_of_threads; i ++)
  102. {
  103. threads[i].first = i * len ;
  104. threads[i].last = ( i + 1 != num_of_threads) ? i * len + len : num_of_elements ;
  105. if(pthread_create(&(threads[i].tid),&pattr, node_method, (void *)&(threads[i])))
  106. perror("pthread create");
  107. }
  108. vec_next[0] = 0;
  109. vec_next[num_of_elements - 1] = 0;
  110. pthread_barrier_wait(&barr1);
  111. for ( i = 1 ; i <= (int)((double)time_intervals/step); i ++)
  112. { //явный метод Эйлера. начало
  113. pthread_barrier_wait(&barr2);
  114. time_moment = i ;
  115. if (time_moment + 1 < (int)((double)time_intervals/(step * 100)) )
  116. { //краевые значения для одной десятой времени работы
  117. vec_next[0 ] = R*IA ;
  118. vec_next[num_of_elements - 1] = R*IA ;
  119. }
  120. else if(time_moment + 1 < (int)((double)time_intervals/(step )))
  121. { //краевые значения для остального времени
  122. vec_next[ 0 ] = vec[1];
  123. vec_next[ num_of_elements - 1] = vec[ num_of_elements - 2];
  124. }
  125. if (argc >= 5)
  126. {
  127. print_nodes(vec_next, &gp) ; //вывод результатов визуализации
  128. }
  129. p = vec ;
  130. vec = vec_next ;
  131. vec_next = p ;
  132. pthread_barrier_wait(&barr1);
  133. }done = 1 ;
  134. gettimeofday(&tv2, &tz);
  135. dtv.tv_sec= tv2.tv_sec -tv1.tv_sec;
  136. dtv.tv_usec=tv2.tv_usec-tv1.tv_usec;
  137. if(dtv.tv_usec<0)
  138. {
  139. dtv.tv_sec--; dtv.tv_usec+=1000000;
  140. }
  141. printf("Time:%ld.%ld\n",(dtv.tv_sec*1000000+dtv.tv_usec)/1000000,(dtv.tv_sec*1000000+dtv.tv_usec)%1000000); //время работы
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement