Tworzenie programów równoległych Krzysztof Banaś Obliczenia równoległe 1
Tworzenie programów równoległych W procesie tworzenia programów równoległych istnieją dwa kroki o zasadniczym znaczeniu: wykrycie dostępnej współbieżności w trakcie realizacji programu określenie koniecznej synchronizacji lub wymiany komunikatów pomiędzy procesami lub wątkami realizującymi program Pierwszy z tych kroków często ma charakter bardziej twórczy, drugi bardziej techniczny (zakłada znajomość modelu programowania) Jednym z najważniejszych wymagań stawianych programom równoległym jest przenośność możliwość uruchomienia na maszynie o dowolnej liczbie procesorów/rdzeni Krzysztof Banaś Obliczenia równoległe 2
Wzorce programowania równoległego Zarządca wykonawcy (manager worker, master slave), często realizowane za pomocą puli wątków (thread pool) Dziel i rządź (divide and conquer) i inne wersje dynamicznego, rekursywnego zarządzania obliczeniami (np. fork join) Zrównoleglenie pętli (loop parallelism) Przetwarzanie potokowe (pipelining) Agenci, aktorzy, przetwarzanie sterowane zdarzeniami Map Reduce i wiele innych Wzorce są ogólnymi wskazówkami rozwiązania problemu dekompozycji zadania na równoległe pod zadania, konkretne programy mogą realizować wiele, często odpowiednio zmodyfikowanych, wzorców Krzysztof Banaś Obliczenia równoległe 3
Krzysztof Banaś Obliczenia równoległe 4
Wygodnym sposobem uporządkowania procesu tworzenia programów równoległych jest ujęcie go w ramy specyficznej metodologii Jedną z takich metodologii jest PCAM (Foster 1985) Kolejne litery oznaczają kroki przy tworzeniu programu: P partition, podział zadania na podzadania C communicate, określenie niezbędnej komunikacji, podział danych na wspólne i prywatne, określenie sposobu korzystania z danych, synchronizacja operacji na danych A agglomerate, analiza wariantów podziału M map, uwzględnienie ostatecznej implementacji, odwzorowania na architekturę sprzętu Pierwsze dwa kroki zmierzają do stworzenia poprawnego programu równoległego, kolejne dwa do jego optymalizacji Krzysztof Banaś Obliczenia równoległe 5
Innym sposobem ujęcia metodologii programowania równoległego jest wyróżnienie pięciu podstawowych zadań, które muszą zostać zrealizowane przy tworzeniu programu równoległego: podział (dekompozycja) zadania obliczeniowego na podzadania odwzorowanie zadań na procesy i wątki oraz dalej na elementy przetwarzania: węzły, multi procesory, procesory (rdzenie) podział (dystrybucja) danych pomiędzy elementy pamięci związane z elementami przetwarzania (uwzględniając hierarchię pamięci) określenie koniecznej wymiany danych między procesami (wątkami) oraz odwzorowanie jej na sieć połączeń między procesorami (rdzeniami) określenie koniecznej synchronizacji między zadaniami (=wątkami (procesami) ) Krzysztof Banaś Obliczenia równoległe 6
Przykłady podziałów zadania na podzadania: Podział ze względu na funkcje, zadania (functional decomposition, task decomposition): modelowanie środowiska naturalnego złożony problem optymalizacji Podział struktury danych (data decomposition) sortowanie tablic rozwiązywanie układów równań liniowych Podział w dziedzinie problemu (domain decomposition) symulacje zjawisk fizycznych w przestrzeni rozwiązywanie układów równań liniowych Krzysztof Banaś Obliczenia równoległe 7
Klasyfikacja ze względu na mechanizmy programowe: MPMD (Multiple Program Multiple Data) każdy proces (wątek) realizuje różny kod (najczęściej związany z różnymi plikami binarnymi) najlepiej odpowiada pojęciu równoległości zadań (task parallelism) koniecznym elementem jest komunikacja, dzięki której różne procesy (wątki) uzyskują rozwiązanie pojedynczego zadania obliczeniowego w przypadku implementacji z przesyłaniem komunikatów programowanie równoległe zbliża się do programowania rozproszonego SPMD (Single Program Multiple Data) każdy proces (wątek) realizuje ten sam program (związany z tym samym plikiem binarnym) Krzysztof Banaś Obliczenia równoległe 8
Model SPMD jest znacznie częściej wykorzystywany niż MPMD dla architektur SIMD oznacza wykonywanie tego samego kodu z synchronizacja sprzętową w wariancie SIMT (karty graficzne) możliwe jest zróżnicowanie wykonywanego kodu realizowane poprzez serializację dla architektur MIMD z pamięcią wspólną każdy wątek może realizować różne ścieżki wykonania w kodzie dla architektur MIMD z pamięcią rozproszoną każdy proces wykonuje ten sam kod binarny mechanizmem wprowadzania zróżnicowania danych na których operuje wątek/proces w każdym z powyższych przypadków może być numerowanie procesów/wątków można korzystać także z innych mechanizmów, związanych z konkretnymi środowiskami programowania i wykonania Krzysztof Banaś Obliczenia równoległe 9
Z praktycznego punktu widzenia często rozróżnia się typy przetwarzania równoległego związane z konkretnymi mechanizmami programowymi równoległość zadań, task parallelism każdy wątek/proces otrzymuje do wykonania pewną funkcję przydział zadań może być statyczny lub dynamiczny, wykonanie może być synchroniczne lub asynchroniczne równoległość wykonania pętli, loop parallelism każdy wątek/proces otrzymuje pewną liczbę iteracji pętli do wykonania w modelu takim każdy proces/wątek posiada własny indeks iteracji, który przyjmuje wartości z określonego podzbioru pełnego zbioru wartości indeksów dla pętli Krzysztof Banaś Obliczenia równoległe 10
Ważnym w dziedzinie przetwarzania równoległego jest pojęcie równoległości danych (data parallelism) w sensie węższym oznacza model programowania, w którym programista określa jawnie przydział danych procesom/wątkom oraz operację do wykonania na całości danych, natomiast konkretna realizacja obliczeń przez procesy/wątki, w tym konieczna synchronizacja i komunikacja, jest przeprowadzana przez środowisko wykonania, bez jawnego udziału programisty realizacją tego modelu są języki równoległości danych takie jak np. High Performance Fortran (HPF) w sensie szerszym oznacza model w którym podstawą zrównoleglenia jest podział (dekompozycja) danych, odpowiedni przydział danych wątkom/procesom oraz wykonanie zgodnie z zasadą właściciel przeprowadza obliczenia (owner computes) Krzysztof Banaś Obliczenia równoległe 11
Metodologia tworzenia programów równoległych może wynikać z: przyjętej docelowej architektury sprzętu na którym działać będzie oprogramowanie zakresu podejmowanych zadań: zrównoleglenie istniejącego kodu zrównoleglenie algorytmu opracowanie nowego, równoległego algorytmu i programu rozwiązującego pewne zadanie Krzysztof Banaś Obliczenia równoległe 12
Punkt wyjścia 1 algorytm (lub program) sekwencyjny jeżeli do dyspozycji mamy algorytm lub program sekwencyjny, a nie mamy możliwości lub chęci analizy samego algorytmu (lub ogólniej metody rozwiązywania postawionego problemu) i jednocześnie godzimy się na fakt nieprzenośności programu na platformy bez pamięci wspólnej korzystamy z równoległości na poziomie wątków: za pomocą odpowiednich narzędzi rozdzielamy sekwencje instrukcji (np. kolejne iteracje pętli lub szereg kolejnych wywołań procedur) pomiędzy wątki Krzysztof Banaś Obliczenia równoległe 13
Punkt wyjścia 2 problem do rozwiązania: dokonujemy analizy problemu starając się podzielić zadanie obliczeniowe na podzadania możliwe do wykonania równoległego: podział funkcji (functional decomposition) podział struktury danych (data decomposition) podział obszaru problemowego (domain decomposition) określamy konieczną wymianę informacji między podzadaniami w celu poprawnej i efektywnej realizacji obliczeń wyróżniamy dane współdzielone globalnie i między grupami podzadań prywatne dla podzadań Krzysztof Banaś Obliczenia równoległe 14
Punkt wyjścia 2 problem do rozwiązania(cd.): wybieramy model do programowania i wykonania programu: równoległości z pamięcią wspólną równoległości z przesyłaniem komunikatów hybrydowy dobieramy stosowne narzędzia, dopasowując je np. do platformy sprzętowej (środowiska programowania HPF, OpenMP, MPI, OpenCL, wielowątkowość wbudowana w języki programowania lub inne) implementując problem dokonujemy ostatecznego odwzorowania obliczeń na architekturę systemu komputerowego i optymalizacji pod względem wybranych kryteriów Krzysztof Banaś Obliczenia równoległe 15
Podsumowanie Praktyczne alternatywy modelu programowania: programowanie sekwencyjne ze zrównolegleniem niejawnym: poprzez układ procesora superskalarnego poprzez automatyczny kompilator zrównoleglający programowanie w językach równoległości danych programowanie w modelu z pamięcią wspólną programowanie w modelu z przesyłaniem komunikatów programowanie w modelu hybrydowym Krzysztof Banaś Obliczenia równoległe 16
Prosty przykład #include<pthread.h> #define LICZBA 100 #define LICZBA_W 4 pthread_mutex_t muteks; int suma=0; pthread_t watki[liczba_w]; int main( int argc, char *argv[] ){ int i; indeksy[liczba_w]; for(i=0;i<liczba_w;i++) indeksy[i]=i; pthread_mutex_init( &muteks, NULL); for(i=0; i<liczba_w; i++ ) pthread_create( &watki[i], NULL, suma_w, (void *) &indeksy[i] ); for(i=0; i<liczba_w; i++ ) pthread_join( watki[i], NULL ); printf( suma = %d\n,suma); } Krzysztof Banaś Obliczenia równoległe 17
Prosty przykład void *suma_w( void *arg_wsk){ int i, moj_id, moja_suma=0; moj_id = *( (int *) arg_wsk ); j=liczba/liczba_w; for( i=j*moj_id+1; i<=j*(moj_id+1); i++){ moja_suma += i; } pthread_mutex_lock( &muteks ); suma += moja_suma; pthread_mutex_unlock( &muteks ); pthread_exit( (void *)0); } Krzysztof Banaś Obliczenia równoległe 18
Prosty przykład Prosty przykład z poprzednich slajdów łączy w sobie kilka wzorców, modeli, sposobów programowania: można go utworzyć na podstawie podziału w dziedzinie problemu lub podziału danych realizuje statyczną równoległość zadań realizuje wzorzec zarządca wykonawcy wykonanie odbywa się w modelu SPMD jest w rzeczywistości sposobem na zrównoleglenie pętli w środowiskach wielowątkowych Krzysztof Banaś Obliczenia równoległe 19