Nie można nauczyć człowieka niczego,
można tylko pomóc odnaleźć mu to
w nim samym - Galileusz
Kurs jest częścią programu Xtreme Computing.
Autorem kursu jest Paweł Przybyłowicz - asystent na Wydziale Matematyki Stosowanej AGH.
Kurs OpenMP - pierwsze kroki
Kilka słów wstępu
Rozpoczynamy cykl lekcji mających na celu przybliżenie programowania równoległego
z użyciem standardu
OpenMP.
Lekcje te nie będą miały charakteru wykładu akademickiego - celem ich jest przedstawienie
czytelnikowi, na prostych przykładach,
w jaki sposób korzystać
z dobrodziejstw tego standardu, bez zbytniego
zagłębiania się w szczegóły techniczne. Zatem użycie każdej dyrektywy, czy też konstrukcji,
będzie zobrazowane programem
i na nim będziemy tłumaczyć jej działanie. Mamy
nadzieję, że nawet użytkownikowi nieobeznanemu
z programowaniem równoległym, taki
sposób przedstawienia materiału umożliwi napisanie konkretnego programu bez konieczności
przebrnięcia wcześniej przez całą dokumentację standardu
OpenMP. Oczywiście
po zapoznaniu się
z każdym omawianym zagadnieniem zachęcamy do przestudiowania
ścisłego opisu danej dyrektywy, znajdującej się
w rzeczonej dokumentacji.
Z doświadczenia wiemy, że taka metoda nauki, nie tylko programowania, jest bardzo
skuteczna, gdyż:
- Często jeden przykład tłumaczy więcej niż cała dokumentacja.
- Zdarza się, że dokumentacja nie zawiera przykładów, przez co skazuje czytelnika na dylematy
typu ok, ale jak to zastosować w moim programie?.
- Na początku techniczne opisy mogą zaciemnić sedno sprawy, które często okazuje się wcale
nietrudne do zrozumienia.
Środowisko programistyczne
Wszystkie programy przedstawione
w niniejszym kursie były kompilowane
i uruchamiane na komputerze z procesorem Intel Core
2 Quad. Używaliśmy
kompilatorów Intel
i GNU GCC. Kompilacja aplikacji program.c, wykorzystującej
OpenMP, przy użyciu kompilatora GCC
i ICC wygląda następująco:
icc -openmp program.c -o program
gcc -fopenmp program.c -o program
Jeśli chodzi
o wykorzystanie standardu OpenMP
w środowisku Visual Studio,
to taka możliwość istnieje począwszy od wersji
z 2005 roku. Aby
z niej
skorzystać należy odpowiednio skonfigurować właściwości projektu (wybrać
Configuration
Properties -> C/C++ -> Language i ustawić opcję
OpenMP Support na
Yes).
W tym miejscu podzielimy się z czytelnikami uwagą ogólną. Okazuje się bowiem, że
niektóre programy kompilowane ICC działają szybciej niż kompilowane GCC i vice versa.
Dlatego nie należy wysuwać ogólnych wniosków, typu ten kompilator jest lepszy od tamtego itp.
Zachowanie programu zależy też od maszyny na której ten program jest wykonywany. Jest oczywiste,
że kompilator ICC zoptymalizowany jest pod kątem procesorów firmy Intel. Z drugiej strony GNU GCC
gwarantuje większą uniwersalność. Polecamy, o ile to możliwe, kompilować każdy program
przy użyciu obydwu kompilatorów i indywidualnie wyciągać odpowiednie wnioski.
Wątki rzeczywiste i wirtualne
Będziemy rozróżniać
wątki rzeczywiste oraz
wątki wirtualne. Wątki
rzeczywiste utożsamiamy
z dostępnymi rdzeniami czy też procesorami. Wątki wirtualne
są to wątki ręcznie utworzone przez program na jego potrzeby. W przypadku procesorów wielordzeniowych
optymalna sytuacja zachodzi, gdy każdy jeden wątek wirtualny jest obsługiwany przez jeden rdzeń.
Jeśli mamy procesor jednordzeniowy
i utworzymy np. 4 wątki i jeśli
dane zadanie wykonujemy na tych wątkach to nie uzyskamy przyspieszenia obliczeń, gdyż te wątki
wirtualne są tak naprawdę obsługiwane sekwencyjnie przez jeden procesor - gdy działa jeden
z nich pozostałe czekają
w kolejce. W tym przykładzie mamy
więc cztery wątki wirtualne
i jeden rzeczywisty. Spodziewane przyspieszenie obliczeń
uzyskamy wykonując program na procesorach wielordzeniowych, na których mamy dostępne co najmniej
dwa wątki rzeczywiste (czyli co najmniej dwa rdzenie)
i wśród których rozdzielamy
zadania wykonywane przez ten program. Przykładowo załóżmy, że mamy procesor dwurdzeniowy. Jeśli
program utworzy cztery wątki, to teraz każdy rdzeń może obsługiwać po dwa wątki albo jeden rdzeń
będzie obsługiwał trzy wątki
a drugi tylko jeden.
Kurs OpenMP - pierwsze kroki
Mamy nadzieję, że ten kurs ułatwi Ci przejście z sekwencyjnego stylu działania na myślenie
i programowanie w sposób równoległy. Obszar ten jest jedną
z najdynamiczniej rozwijających się gałęzi przemysłu informatycznego.
I jak
to zazwyczaj się
w informatyce dzieje, niedługo ta
gałąź stanie się najprawdopodobniej
standardem. Dlatego uważamy, że dobrze być przygotowanym na taką ewentualność wcześniej, niż dać
się zaskoczyć.
Zapraszamy do lektury i życzmy owocnej nauki.
- Krok 1 - Zrównoleglanie pętli, opcje private i shared.
- Krok 2 - Zrównoleglanie pętli, opcje default i schedule.
- Krok 3 - Wyodrębnianie obszarów zrównoleglanych, opcja sections.
- Krok 4 - Zrównoleglanie pętli, opcja reduction.
- Krok 5 - Dyrektywy sterujące if i num_threads.
- Krok 6 - Prosty problem praktyczny.
- Krok 7 - Dyrektywy barier i nowait.
Informacje o standardzie