Programowanie systemów z pamięcią wspólną
- specyfikacja OpenMP
OpenMP
Przenośność oprogramowania
Model SPMD
Szczegółowe wersje (bindings) dla różnych języków programowania
Elementy składowe:
dyrektywy dla kompilatorów
funkcje biblioteczne
zmienne środowiskowe
OpenMP – składnia dyrektyw
format ( dla powiązania z językami C i C++ ):
#pragma omp nazwa_dyrektywy lista_klauzul znak_nowej_linii
najważniejszymi z dyrektyw są dyrektywy podziału pracu (work sharing constructs), występujące w obszarze równoległym i
stosowane do rozdzielenia poleceń realizowanych przez poszczególne procesory
najważniejsze klauzule określają sposób traktowania zmiennych przez wątki w obszarze równoległym
każda dyrektywa posiada swój własny zestaw dopuszczalnych klauzul
OpenMP – składnia dyrektyw
parallel
#pragma omp parallel lista_klauzul { /* obszar równoległy */ }
lista_klauzul (pusta lub dowolna kombinacja poniższych):
if( warunek )
num_threads ( liczba )
klauzule_zmiennych ( private, firstprivate, shared, reduction ) - za chwilę
inne
OpenMP – liczba wątków
liczbę wątków można próbować określić jawnie poprzez:
użycie klauzuli num_threads w dyrektywie parallel, np.:
#pragma omp parallel num_threads(10)
wywołanie procedury omp_set_num_threads, np.:
omp_set_num_threads(10);
ustalenie zmiennej środowiskowej OMP_NUM_THREADS,np.:
$ set OMP_NUM_THREADS = 10
w pozostałych przypadkach liczba wątków jest ustalana przez implementację OpenMP w danym systemie
istnieje możliwość dynamicznego ustalania liczby wątków (aby np.
umożliwić działanie dla systemów, które nie dysponują liczbą określoną poprzez num_threads)
Narzut OpenMP
OpenMP – funkcje biblioteczne
funkcje związane ze środowiskiem wykonania:
plik nagłówkowy: omp.h
składnia funkcji set: void funkcja( int );
składnia pozostałych funkcji: int funkcja( void )
omp_set_num_threads - ustalenie liczby wątków
omp_get_num_threads - pobranie liczby wątków
omp_get_num_procs - pobranie liczby procesorów
omp_get_thread_num - pobranie rangi konkretnego wątku (master - 0)
omp_in_parallel - sprawdzenie wykonania równoległego
omp_get_max_threads - pobranie maksymalnej liczby wątków
omp_set_dynamic, omp_get_dynamic – dostosowywanie liczby wątków
omp_set_nested, omp_get_nested – umożliwianie zagnieżdzania
OpenMP – funkcje biblioteczne
funkcje obsługi zamków:
typ zamka: omp_lock_t; argumentem funkcji jest zawsze omp_lock_t*
omp_init_lock - inicjowanie
omp_destroy_lock - niszczenie
omp_set_lock - zamykanie
omp_test_lock - próba zamykania bez blokowania
omp_unset_lock - otwieranie
wersje dla zagnieżdżonych zamków
funkcje pomiaru czasu:
omp_get_wtime – czas zegara
omp_get_wtick – rozdzielczość (dokładność) zegara
OpenMP – makro preprocesora i zmienne środowiskowe
#ifdef _OPENMP
printf(„Kompilator rozpoznaje dyrektywy OpenMP\n”);
#endif
Zmienne środowiskowe
OMP_SCHEDULE określenie – dla równoległych pętli z klauzulą schedule(runtime)
OMP_NUM_THREADS liczba
OMP_DYNAMIC TRUE/FALSE
OMP_NESTED TRUE/FALSE
OpenMP - przykład
#include<omp.h>
int main(){
#ifdef _OPENMP
printf("Kompilator rozpoznaje dyrektywy OpenMP\n");
#endif
int lwat; printf("maksymalna liczba watkow - "); scanf("%d",&lwat);
omp_set_num_threads(lwat);
printf("aktualna liczba watkow %d, moj ID %d\n",
omp_get_num_threads(), omp_get_thread_num());
#pragma omp parallel {
printf("aktualna liczba watkow %d, moj ID %d\n",
OpenMP – traktowanie zmiennych
klauzule współdzielenia zmiennych:
shared – zmienna wspólna wątków
private – zmienna lokalna wątków
firstprivate – zmienna lokalna wątków z kopiowaną wartością początkową
lastprivate – zmienna lokalna wątków z wartością końcową równą wartości jaka byłaby przy wykonaniu sekwencyjnym
inne
dyrektywa
threadprivate (zasięg ważności deklaracji jest taki jak zasięg ważności deklarowanych nazw)#pragma omp threadprivate (lista_zmiennych) znak_nowej_linii
OpenMP – traktowanie zmiennych
zmienna jest wspólna (dostępna wszystkim wątkom) jeśli:
istnieje przed wejściem do obszaru równoległego i nie
występuje w dyrektywach i klauzulach czyniących ją prywatną
została zdefiniowana wewnątrz obszaru równoległego jako zmienna statyczna
zmienna jest prywatna (lokalna dla wątku) jeśli
została zadeklarowana dyrektywą threadprivate
została umieszczona w klauzuli private lub podobnej (firstprivate, lastprivate, reduction )
została zdefiniowana wewnątrz obszaru równoległego jako zmienna automatyczna
jest zmienną sterującą równoległej pętli for
OpenMP – pozostałe dyrektywy
critical
#pragma omp critical nazwa znak_nowej_linii {....}
atomic
#pragma omp atomic znak_nowej_linii
flush
#pragma omp flush lista_zmiennych znak_nowej_linii
barrier
#pragma omp barrier znak_nowej_linii
➔ ordered