Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.57 KB | None | 0 0
  1. #define N 1000000
  2.  
  3. void showElapsed(int id,const char *m);
  4. void showVector(int *v, int n, int id);
  5. int * merge(int *v1, int n1, int *v2, int n2);
  6. void swap(int *v, int i, int j);
  7. void qsort(int *v, int left, int right);
  8.  
  9. double startTime, stopTime;
  10.  
  11. void showElapsed(int id,const char *m)
  12. {
  13.     printf("%d: %s %f secs\n", id, m, (clock() - startTime) / CLOCKS_PER_SEC);
  14. }
  15.  
  16. void showVector(int *v, int n, int id)
  17. {
  18.     int i;
  19.     printf("%d: ", id);
  20.     for (i = 0; i < n; i++)
  21.         printf("%d ", v[i]);
  22.     putchar('\n');
  23. }
  24.  
  25. int * merge(int *v1, int n1, int *v2, int n2)
  26. {
  27.     int i, j, k;
  28.     int * result;
  29.  
  30.     result = (int *)malloc((n1 + n2) * sizeof(int));
  31.  
  32.     i = 0; j = 0; k = 0;
  33.     while (i < n1 && j < n2)
  34.         if (v1[i] < v2[j])
  35.         {
  36.             result[k] = v1[i];
  37.             i++; k++;
  38.         }
  39.         else
  40.         {
  41.             result[k] = v2[j];
  42.             j++; k++;
  43.         }
  44.     if (i == n1)
  45.         while (j < n2)
  46.         {
  47.             result[k] = v2[j];
  48.             j++; k++;
  49.         }
  50.     else
  51.         while (i < n1)
  52.         {
  53.             result[k] = v1[i];
  54.             i++; k++;
  55.         }
  56.     return result;
  57. }
  58.  
  59. void swap(int *v, int i, int j)
  60. {
  61.     int t;
  62.     t = v[i];
  63.     v[i] = v[j];
  64.     v[j] = t;
  65. }
  66.  
  67. void qsort(int *v, int left, int right)
  68. {
  69.     int i, last;
  70.     if (left >= right)
  71.         return;
  72.     swap(v, left, (left + right) / 2);
  73.     last = left;
  74.     for (i = left + 1; i <= right; i++)
  75.         if (v[i] < v[left])
  76.             swap(v, ++last, i);
  77.     swap(v, left, last);
  78.     qsort(v, left, last - 1);
  79.     qsort(v, last + 1, right);
  80. }
  81.  
  82. int main(int argc, char **argv)
  83. {
  84.     int * data;
  85.     int * chunk;
  86.     int * other;
  87.     int m, n = N;
  88.     int id, p;
  89.     int s;
  90.     int i;
  91.     int step;
  92.     MPI_Status status;
  93.  
  94.     startTime = clock();
  95.  
  96.     MPI_Init(&argc, &argv);
  97.     MPI_Comm_rank(MPI_COMM_WORLD, &id);
  98.     MPI_Comm_size(MPI_COMM_WORLD, &p);
  99.  
  100.     showElapsed(id, "MPI setup complete");
  101.     int r;
  102.    
  103.  
  104.     s = n / p;
  105.     r = n % p;
  106.     data = (int *)malloc((n + s - r) * sizeof(int));
  107.     if (id == 0)
  108.     {
  109.         srand(clock());
  110.         for (i = 0; i < n; i++)
  111.             data[i] = rand();
  112.         if (r != 0)
  113.         {
  114.             for (i = n; i < n + s - r; i++)
  115.                 data[i] = 0;
  116.             s = s + 1;
  117.         }
  118.         showElapsed(id, "generated the random numbers");
  119.  
  120.         MPI_Bcast(&s, 1, MPI_INT, 0, MPI_COMM_WORLD);
  121.         chunk = (int *)malloc(s * sizeof(int));
  122.         MPI_Scatter(data, s, MPI_INT, chunk, s, MPI_INT, 0, MPI_COMM_WORLD);
  123.  
  124.         showElapsed(id, "scattered data");
  125.  
  126.         qsort(chunk, 0, s - 1);
  127.  
  128.         showElapsed(id, "sorted");
  129.     }
  130.     else
  131.     {
  132.         MPI_Bcast(&s, 1, MPI_INT, 0, MPI_COMM_WORLD);
  133.         chunk = (int *)malloc(s * sizeof(int));
  134.         MPI_Scatter(data, s, MPI_INT, chunk, s, MPI_INT, 0, MPI_COMM_WORLD);
  135.  
  136.         showElapsed(id, "got data");
  137.  
  138.         qsort(chunk, 0, s - 1);
  139.  
  140.         showElapsed(id, "sorted");
  141.     }
  142.  
  143.     step = 1;
  144.     while (step < p)
  145.     {
  146.         if (id % (2 * step) == 0)
  147.         {
  148.             if (id + step < p)
  149.             {
  150.                 MPI_Recv(&m, 1, MPI_INT, id + step, 0, MPI_COMM_WORLD, &status);
  151.                 other = (int *)malloc(m * sizeof(int));
  152.                 MPI_Recv(other, m, MPI_INT, id + step, 0, MPI_COMM_WORLD, &status);
  153.                 showElapsed(id, "got merge data");
  154.                 chunk = merge(chunk, s, other, m);
  155.                 showElapsed(id, "merged data");
  156.                 s = s + m;
  157.             }
  158.         }
  159.         else
  160.         {
  161.             int near = id - step;
  162.             MPI_Send(&s, 1, MPI_INT, near, 0, MPI_COMM_WORLD);
  163.             MPI_Send(chunk, s, MPI_INT, near, 0, MPI_COMM_WORLD);
  164.             showElapsed(id, "sent merge data");
  165.             break;
  166.         }
  167.         step = step * 2;
  168.     }
  169.     if (id == 0)
  170.     {
  171.         FILE * fout;
  172.  
  173.         stopTime = clock();
  174.         printf("%d; %d processors; %f secs\n", s, p, (stopTime - startTime) / CLOCKS_PER_SEC);
  175.  
  176.         showElapsed(id, "opening out file");
  177.         fout = fopen("result", "w");
  178.         for (i = 0; i < s; i++)
  179.             fprintf(fout, "%d\n", chunk[i]);
  180.         fclose(fout);
  181.         showElapsed(id, "closed out file");
  182.     }
  183.     MPI_Finalize();
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement