Advertisement
desdemona

cobyło3tygodnietemu

May 17th, 2015
685
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.85 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <omp.h>
  5. #include <sys/time.h>
  6.  
  7. #define PACKET_COUNT 100
  8. #define RESOLUTION 10000
  9.  
  10. #define A 0
  11. #define B 100
  12.  
  13. typedef struct
  14. {
  15.   void *data;
  16.  
  17. } t_data;
  18.  
  19. typedef struct
  20. {
  21.   void *result;
  22. } t_result;
  23.  
  24. double dtime()
  25. {
  26.   double tseconds = 0.0;
  27.   struct timeval mytime;
  28.   gettimeofday (&mytime, (struct timezone *) 0);
  29.   tseconds = (double) (mytime.tv_sec + mytime.tv_usec * 1.0e-6);
  30.   return (tseconds);
  31. }
  32.  
  33. double f(double x)
  34. {                               // the function to be integrated
  35.   return sin (x) * sin (x) / x;
  36. }
  37.  
  38. void process(t_data data, t_result result)
  39. {
  40.   double r_a=((double *)data.data)[0];
  41.   double r_b=((double *)data.data)[1];
  42.   double integrate = 0;
  43.   double r_length = (r_b - r_a) / RESOLUTION;
  44.   double x = r_a;
  45.   int i;
  46. // a simple implementation of the integrate
  47.   for (i = 0; i < RESOLUTION; i++)
  48.     {
  49.       integrate += f(x);
  50.       x += r_length;
  51.     }
  52.   *((double *) result.result) = (integrate / RESOLUTION);       // store the result
  53. }
  54.  
  55. t_result* allocate_results(int *packet_count)
  56. {
  57.   int i;
  58. // prepare space for results
  59.   t_result *r_results =
  60.     (t_result *) malloc (sizeof (t_result) * PACKET_COUNT);
  61.   if (r_results == NULL)
  62.     {
  63.       perror ("Not enough memory");
  64.       exit (-1);
  65.     }
  66.   for (i = 0; i < PACKET_COUNT; i++)
  67.     {
  68.       r_results[i].result = malloc (sizeof (double));
  69.       if (r_results[i].result == NULL)
  70.         {
  71.           perror ("Not enough memory");
  72.           exit (-1);
  73.         }
  74.     }
  75.   *packet_count = PACKET_COUNT;
  76.   return r_results;
  77. }
  78.  
  79. t_data *
  80. generate_data (int *packet_count)
  81. {
  82. // prepare the input data
  83. // i.e. the given range is to be divided into packets
  84.   int i;
  85.   double a = A, b = B;
  86.   double packet_size = (b - a) / PACKET_COUNT;
  87.   t_data *p_packets;
  88.   double *p_data;
  89.   double r_a, r_b;
  90. // prepare PACKET_COUNT number of packets
  91.   t_data *packets = (t_data *) malloc (sizeof (t_data) * PACKET_COUNT);
  92.   if (packets == NULL)
  93.     {
  94.       perror ("Not enough memory");
  95.       exit (-1);
  96.     }
  97.   r_a = a;
  98.   r_b = a + packet_size;
  99.   p_packets = packets;          // pointer to the beginning of the packets
  100.   for (i = 0; i < PACKET_COUNT; i++)
  101.     {
  102.       packets[i].data = malloc (2 * sizeof (double));
  103.       if (packets[i].data == NULL)
  104.         {
  105.           perror ("Not enough memory");
  106.           exit (-1);
  107.         }
  108. // populate the packet with the data
  109.       p_data = (double *) packets[i].data;
  110.       *p_data = r_a;
  111.       *(p_data + 1) = r_b;
  112.       r_a += packet_size;
  113.       r_b += packet_size;
  114.     }
  115.   *packet_count = PACKET_COUNT;
  116.   return packets;
  117. }
  118.  
  119. t_data *data;
  120. t_result *results;
  121.  
  122. main (int argc, char **argv)
  123. {
  124. // prepare the input data
  125. // i.e. the given range is to be divided into packets
  126. // now the main processing loop using OpenMP
  127.   int counter;
  128.   int my_data;
  129.   double result;
  130.   int i;
  131.   int packet_count;
  132.   int results_count;
  133.   double t_start, t_stop, t_total, t_current, t_min;
  134.   int t_counter = 0;
  135.   t_min = B;
  136.   do
  137.     {
  138. // generate input data
  139.       data = generate_data (&packet_count);
  140. // allocate memory for results
  141.       results = allocate_results (&results_count);
  142.       counter = 0;
  143.       t_start = dtime ();
  144. // launch threads in parallel – the number will be set using an environment variable
  145. #pragma omp parallel private(my_data) shared(counter)
  146.       {
  147.         do
  148.           {
  149. // each thread will try to get its data from the available list - synchronization is needed
  150. #pragma omp critical
  151.             {
  152.               my_data = counter;
  153.               counter++;        // also write result to the counter
  154.             }
  155. // process and store result -- this can be done without synchronization
  156.             if (my_data < PACKET_COUNT)
  157.               process (data[my_data], results[my_data]);        // note that processing
  158. // may take various times for various data packets
  159.           }
  160.         while (counter < PACKET_COUNT); // otherwise simply exit because
  161. // there are no more data packets to process
  162.       }
  163.       t_stop = dtime ();        // stop benchmarking
  164. #pragma omp barrier
  165. // now just add results
  166.       result = 0;
  167.       for (i = 0; i < PACKET_COUNT; i++)
  168.         {
  169.           result += *((double *) results[i].result);
  170.         }
  171.       t_counter++;
  172.       t_current = t_stop - t_start;
  173.       if (t_current < t_min)
  174.         t_min = t_current;
  175. // repeat a few times if the total execution time is short!
  176.     }
  177.   while ((t_counter < 4) && (t_current < 100));
  178.  
  179.       for (i = 0; i < PACKET_COUNT; i++)
  180.         {
  181.  
  182.           printf("%d,%.5f,%.5f\n", i,
  183.                  ((double *)data[i].data)[1],
  184.                  *((double *)results[i].result));
  185.         }
  186.  
  187.  
  188.   printf ("\nFinished");
  189.   printf ("\nThe total value of the integrate is %.5f\n", result);
  190.   printf ("\nTotal time elapsed=%.8f\n", t_min);
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement