Advertisement
filip710

asdaasd

Jan 21st, 2020
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. 1. Napišite paralelni program za množenje dviju kvadratnih matrica veličine 2000x2000, popunjenih s brojevima s pomičnim zarezom dvostruke preciznosti (double). Pokušajte napisati program tako da ima najveću moguću učinkovitost pri paralelnom korištenju resursa.
  2.  
  3.  
  4.  
  5. #include <mpi.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <time.h>
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12. int matrixSize, rank, size;
  13.  
  14. double *sendA, *sendB, *finalC, *recA, *recC;
  15. //definirnje varijabli za mjerenje userCPU i realCPU
  16. //double t1, t2;
  17. MPI::Init(argc, argv);
  18.  
  19. size = MPI::COMM_WORLD.Get_size();
  20. rank = MPI::COMM_WORLD.Get_rank();
  21.  
  22. if (rank == 0)
  23. {
  24. matrixSize = 2000;
  25. printf("rows is %d \n", matrixSize);
  26.  
  27. sendA = new double[matrixSize * matrixSize];
  28. sendB = new double[matrixSize * matrixSize];
  29. finalC = new double[matrixSize * matrixSize];
  30.  
  31. for (int i = 0; i < matrixSize; i++)
  32. for (int j = 0; j < matrixSize; j++)
  33. {
  34. sendA[i * matrixSize + j] = i + 1;
  35. }
  36. for (int i = 0; i < matrixSize; i++)
  37. for (int j = 0; j < matrixSize; j++)
  38. {
  39. sendB[i * matrixSize + j] = j + 1;
  40. }
  41. }
  42.  
  43. MPI::COMM_WORLD.Barrier();
  44. MPI::COMM_WORLD.Bcast(&matrixSize, 1, MPI::INT, 0);
  45. //Start time t1
  46. //t1 = MPI::Wtime();
  47. recA = new double[matrixSize / size * matrixSize];
  48. if (sendB == NULL)
  49. {
  50. sendB = new double[matrixSize * matrixSize];
  51. }
  52. recC = new double[matrixSize / size * matrixSize];
  53.  
  54.  
  55. MPI::COMM_WORLD.Scatter(sendA, matrixSize * matrixSize / size, MPI::DOUBLE, recA, matrixSize * matrixSize / size, MPI::DOUBLE, 0);
  56.  
  57.  
  58. MPI::COMM_WORLD.Bcast(sendB, matrixSize * matrixSize, MPI::DOUBLE, 0);
  59.  
  60.  
  61. for (int i = 0; i < (matrixSize / size); i++)
  62. for (int j = 0; j < matrixSize; j++)
  63. {
  64. recC[i * matrixSize + j] = 0;
  65. for (int k = 0; k < matrixSize; k++)
  66. recC[i * matrixSize + j] += recA[i * matrixSize + k] * sendB[k * matrixSize + j];
  67. }
  68.  
  69. MPI::COMM_WORLD.Barrier();
  70. MPI::COMM_WORLD.Gather(recC, matrixSize * matrixSize / size, MPI::DOUBLE, finalC, matrixSize * matrixSize / size, MPI::DOUBLE, 0);
  71. MPI::COMM_WORLD.Barrier();
  72. //End time t2
  73. //t2 = MPI::Wtime();
  74.  
  75. /*
  76. IZRACUN realCPU Time
  77. double totalTime;
  78. double elapsedTime = t2-t1;
  79. MPI::COMM_WORLD.Reduce( &elapsedTime, &totalTime, 1, MPI::DOUBLE, MPI::SUM, 0 );
  80. */
  81.  
  82. if (rank == 0)
  83. {
  84. /*
  85. IZRACUN MLFPOS
  86. int n_flop = 2 * matrixSize * matrixSize * matrixSize;
  87. double time = t2- t1;
  88. double mflops = n_flop / (time * 1000000);
  89. */
  90. for (int i = 0; i < matrixSize; i++)
  91. {
  92. for (int j = 0; j < matrixSize; j++)
  93. printf(" %.2f ", finalC[i * matrixSize + j]);
  94. printf("\n");
  95. }
  96. printf("Send A: \n");
  97. for (int i = 0; i < matrixSize; i++)
  98. {
  99. for (int j = 0; j < matrixSize; j++)
  100. printf(" %.2f ", sendA[i * matrixSize + j]);
  101. printf("\n");
  102. }
  103. printf("Send B: \n");
  104. for (int i = 0; i < matrixSize; i++)
  105. {
  106. for (int j = 0; j < matrixSize; j++)
  107. printf(" %.2f ", sendB[i * matrixSize + j]);
  108. printf("\n");
  109. }
  110. }
  111.  
  112. MPI::Finalize();
  113. return 0;
  114. }
  115. 2. Analizirati kako podijeliti posao na dvije arhitekture (računalni splet i stolno računalo s višejezgrenim procesorom) koristeći a. MPI b. OpenMP c. MLP (MPI + OpenMP).
  116.  
  117. a) primjer rješenja je u 1. zadatku - retci prve matrice se podijele na sve procese pomoću scattera, a cijela druga matrica se broadcasta svim procesima. Nakon što svaki proces izračuna svoj dio matrice, rezultati se skupe u konačnu matricu koristeći Gather.
  118. b) Za OpenMP bi se trebala koristiti #pragma omp parallel for direktiva sa dijeljenim i privatnim varijablama, te bi u tom slučaju, različite niti računale različite dijelove matrice
  119.  
  120. c) Kod MLP arhitekture kombinirale bi se prethodne dvije metode, gdje bi se različitim procesima Scatterali dijelovi matrice, a zatim bi različite niti pojedinačnih procesa računale određene dijelove matrice.
  121.  
  122. 3. Izračunati postignut MFLOPS
  123.  
  124. MFLOPS u našem zadatku nismo mogli izračunati zbog problema s Wtime funkcijom (kao što je opisano u komentarima koda), no generalno se MFLOPS za množenje matrica računa kao broj operacija * n^3.
  125.  
  126. 4. Odrediti „user CPU time“ i „real CPU time“ programa
  127.  
  128. User CPU time je ukupno vrijeme koje korisnik percipira koje je potrebno za izračun matrice. Real CPU time je suma vremena izvođenja svakog pojedinačnog procesa, kojeg smo u kodu izračunali kao totalTime pomoću Reduce funkcije.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement