Advertisement
Alan468

PRIR Obliczanie PI sekwencyjnie i równolegle

Oct 12th, 2017
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.48 KB | None | 0 0
  1. // Alloner & JuanCorp PRIR 2017-10-12
  2. #include <Windows.h>
  3. #include <time.h>
  4. #include <iostream>
  5. #include <math.h>
  6. #include <conio.h>
  7. #include <cstdio>
  8.  
  9. using namespace std;
  10.  
  11. // Dane przekazywane do watku
  12. struct MyData
  13. {
  14.     int ID; // Id wątku
  15.     int IndexStart; // Poczatek
  16.     int IndexStop;  // i koniec przedziału do obliczeń
  17. };
  18.  
  19. double *SeqResults;
  20.  
  21. // Obliczanie PI/4 w 'tradycyjny' sposob (z mozliwoscia uzycia z watkami)
  22. double LeibnizMethodSeq(int indexStart, int indexStop)
  23. {
  24.     double Result = 0.0; // Bufor wyniku
  25.  
  26.     // Obliczenia wedlug wzoru ... dla przedzialu
  27.     for (int i = indexStart; i < indexStop; i++)
  28.     {
  29.         if (i % 2 == 0) // Parzysta potega
  30.             Result += 1.0 / (2.0 * i + 1.0);
  31.         else // Nieparzysta potega
  32.             Result -= 1.0 / (2.0 * i + 1.0);
  33.     }
  34.  
  35.     return Result; // Wynik (powinno wyjsc +- PI/4)
  36. }
  37.  
  38. // Funkcja wykonywana przez kazdy watek
  39. DWORD WINAPI LeibnizPart(LPVOID lpParam)
  40. {
  41.     // rzutowanie lpParam na nasz typ
  42.     MyData *Data = (MyData*)lpParam;
  43.     // Przypisanie wyniku 'standardowego' obliczania dla przedzialu danego watku
  44.     // i przypisanie go do odpowiedniego miejsca w buforze
  45.     SeqResults[Data->ID] = LeibnizMethodSeq(Data->IndexStart, Data->IndexStop);
  46.  
  47.     return 0;
  48. }
  49.  
  50. // Obliczanie PI/4 w sposob wielowatkowy
  51. void LeibnizMethodPar(int pressiton, int numberOfThreads)
  52. {
  53.     // Zmienne potrzebna do utworzenia watkow
  54.     MyData *pDataArray = new MyData[numberOfThreads];
  55.     DWORD *dwThreadIdArray = new DWORD[numberOfThreads];
  56.     HANDLE *hThreadArray = new HANDLE[numberOfThreads];
  57.    
  58.     int perThread = pressiton / numberOfThreads;// Obliczenie przedzialow
  59.     int indexStart = 0;// Bufor indexu poczatkowego
  60.  
  61.     for (int i = 0; i < numberOfThreads; i++)
  62.     {
  63.         pDataArray[i].ID = i; // Przypisanie ID watku
  64.         pDataArray[i].IndexStart = indexStart; // Poczatek przedzialu
  65.         pDataArray[i].IndexStop = indexStart + perThread; // Koniec przedzialu
  66.  
  67.         // Jesli ilosc 'pressiton % numberOfThreads != 0' przypisz reszte zakresu do ostatniego watku (np.: 9%4 = 1)
  68.         if (i + 1 == numberOfThreads && pressiton% numberOfThreads != 0)
  69.             pDataArray[i].IndexStop += (pressiton%numberOfThreads);
  70.  
  71.         // Utworzenie watku
  72.         hThreadArray[i] = CreateThread(NULL, 0, LeibnizPart, &pDataArray[i], 0, &dwThreadIdArray[i]);
  73.  
  74.         // przesuniecie zakresu
  75.         indexStart += perThread;
  76.     }
  77.  
  78.     // Czekanie na skonczenie obliczen przez watki
  79.     WaitForMultipleObjects(numberOfThreads, hThreadArray, TRUE, INFINITE);
  80.  
  81.     // Zamykanie uchwytow do watkow
  82.     for (int i = 0; i < numberOfThreads; i++)
  83.         CloseHandle(hThreadArray[i]);
  84.  
  85. }
  86.  
  87. int main()
  88. {
  89.     // Zmienna dla czasomierza
  90.     int TimeStart, TimeStop;
  91.  
  92.     int Pressition = 1600000000; // Dokladnosc
  93.     int Threads = 4; // Ilosc watkow
  94.     double LeibnizResult = 0.0; // Wynik obliczen
  95.  
  96.     // Obliczenia dla metody 'klasycznej' - sekwencyjnej
  97.     printf("Leibniz method sequential\n");
  98.     TimeStart = clock();
  99.     LeibnizResult = LeibnizMethodSeq(0, Pressition);
  100.     TimeStop = clock();
  101.     printf("Result: %.15lf \nTime: %d\n", 4 * LeibnizResult, TimeStop - TimeStart);
  102.  
  103.     printf("\n");
  104.     LeibnizResult = 0.0;
  105.  
  106.     // Obliczenia dla metody wielowatkowej
  107.     printf("Leibniz method parallel\n");
  108.     TimeStart = clock();
  109.     SeqResults = new double[Threads];
  110.     LeibnizMethodPar(Pressition, Threads);
  111.     TimeStop = clock();
  112.  
  113.     // Dodanie wynikow z bufora
  114.     for (int i = 0; i < Threads; i++)
  115.         LeibnizResult += SeqResults[i];
  116.  
  117.     printf("Result: %.15lf \nTime: %d\n", 4 * LeibnizResult, TimeStop - TimeStart);
  118.  
  119.     _getch();
  120.     return 0;
  121. }
  122. // Alloner & JuanCorp PRIR 2017-10-12
  123. // 9,5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement