MPI - ćwiczenia
Transkrypt
MPI - ćwiczenia
Optymalizacja z użyciem klastrów obliczeniowych MPI - ćwiczenia Zadanie 1 Dana jest następująca funkcja f (i), której dziedziną są liczby całkowite dodatnie. Chcemy się dowiedzieć dla ilu spośród liczb całkowitych j od 1 do 2 000 000 000 zachodzi własność: f (j) == c, gdzie liczba całkowita c jest zadana przez użytkownika, jako parametr wywołania programu. Badaną funkcję zdefiniowano następująco: int f (int int int for i) { i4_huge = 2147483647; j, k, value = i; (j = 1; j <= 5; j++) { k = value / 127773; value = 16807 * (value - k * 127773) - k * 2836; if (value <= 0) value = value + i4_huge; } return value; } Opracuj algorytm równoległy z wykorzystaniem biblioteki MPI. Przetestuj swoje rozwiązanie uruchamiając program z wykorzystaniem 1, 2, 4 i 6 wątków. Zadanie 2 Zaimplementuj równoległy algorytm zliczający wszystkie liczby pierwsze znajdujące się w przedziale pomiędzy zerem, a liczbą N wprowadzoną przez użytkownika. Przetestuj swoje rozwiązanie dla przynajmniej N = 107 . Wyświetl ile liczb pierwszych udało Ci się znaleźć oraz oblicz sumę (o podstawie modulo równiej 123) dla wszystkich liczb pierwszych. Zadanie 3 Zaimplementuj operację mnożenia dwóch 3 1 0 2 · 2 −1 3 1 1 macierzy: 1 5 1 1 = 4 2 0 Wykorzystaj algorytm Cannona: – dane są dwie macierze: 3 8 6 A = 7 1 6, 8 4 6 4 2 4 B = 1 8 6 4 2 7 – algorytm rozpoczynamy od tzw. „fazy przygotowawczej”. Tworzymy podmacierze A’, przesuwając rzędy macierzy A w kierunku mniejszych indeksów, oraz B’, przesuwając kolumny macierzy B również w kierunku mniejszych indeksów o numer rzędu/kolumny (zakładając, że numerujemy od 0): 3 8 6 4 8 7 A0 = 1 6 7 , B0 = 1 2 4 6 8 4 4 2 6 – w K krokach dokonujemy przemnożenia wszystkich komórek pomiędzy macierzami A’ i B’, a następnie sumujemy otrzymane wyniki do macierzy tymczasowej (domyślnie wypełnionej zerami). Macierze A’ oraz B’ zostają podane kolejnym przesunięciom (tylko o jedną pozycję). Algorytm powtarzamy do momentu, aż stan podmacierzy nie będzie taki sam, jak w fazie przygotowawczej: • K =0 3 8 6 4 8 7 0 0 0 12 64 42 1 6 7 · 1 2 4 + 0 0 0 = 1 12 28 6 8 4 4 2 6 0 0 0 24 16 24 • K =1 20 76 54 8 6 3 1 2 4 12 64 42 6 7 1 · 4 2 6 + 1 12 28 = 25 26 34 56 48 66 4 8 7 24 16 24 8 4 6 • K =2 6 3 8 4 2 6 20 76 54 44 82 102 7 1 6 · 4 8 7 + 25 26 34 = 53 34 76 4 6 8 1 2 4 56 48 66 60 60 98 Zadanie 4 Gra w życie toczy się na skończonej planszy (płaszczyźnie) podzielonej na kwadratowe komórki. Każda komórka ma ośmiu „sąsiadów”, czyli komórki przylegające do niej bokami i rogami. Każda komórka może znajdować się w jednym z dwóch stanów: może być albo „żywa” (włączona), albo „martwa” (wyłączona). Stany komórek zmieniają się krokowo. Stan wszystkich komórek w danym kroku jest używany do obliczenia stanu wszystkich komórek w kroku następnym. Po obliczeniu wszystkie komórki zmieniają swój stan dokładnie w tym samym momencie. Stan komórki zależy tylko od liczby jej żywych sąsiadów. W grze tej nie ma graczy w dosłownym tego słowa znaczeniu. Udział człowieka sprowadza się jedynie do ustalenia stanu początkowego komórek. Zdefiniowano kilka wzorców reguł generowania, najbardziej rozpowszechnione są reguły wymyślone przez Conwaya (znanego brytyjskiego matematyka). W niniejszym zadaniu jednak przyjmiemy trochę inne reguły. – Martwa komórka, która ma 1 lub 2 żywych sąsiadów, staje się żywa w następnym kroku (rodzisię), – Żywa komórka z 1 albo 2 żywymi sąsiadami pozostaje nadal żywa; przy innej liczbie sąsiadów umiera (z „samotności” albo „zatłoczenia”). Napisz program równoległy (podobnie jak w przypadku innych ćwiczeń w języku C++ oraz modelu z przesyłaniem wiadomości) symulujący dwuwymiarowy binarny automat komórkowy do gry w życie. Przyjmij, że gra rozgrywa się w macierzy 8000 wierszy na 8000 kolumn, która na początku (w kroku 0) ma włączone komórki na obu przekątnych, a pozostałe ma wyłączone. Jaka będzie liczba włączonych komórek w kroku 400?