headerphoto

OpenMP

Kompilacja kodu źródłowego z elementami zrównoleglania

Kod źródłowy z elementami zrównoleglania kompilować będziemy za pomocą popularnego kompilatora GCC. Jest to najpopularniejsze narzędzie do kompilowania źródeł pod systemami UNIX, Linux, czy AmigaOS. Od wersji 4.2 kompilator ten obsługuje standard OpenMP bez potrzeby doinstalowywania go z zewnętrznych źródeł. Na dzień dzisiejszy dostępne są już dystrybucje Linuxa, zawierające kompilator GCC z wbudowaną obsługą OpenMP. Należy do nich OpenSUSE 10.3 oraz najnowsze odmiany Debiana (od wersji 4.0). Programowanie równoległe staje się z dnia na dzień coraz popularniejsze, dlatego należy się spodziewać, że w niedługim czasie większość dystrybucji linuxa zawierać będzie na stałe bibliotekę OpenMP. Oczywiście jeśli korzystamy ze starszej wersji kompilatora GCC, można bez problemów doinstalować na przykład pakiet Omni OpenMP Compiler System1.

Po zakończeniu procesu instalacji OpenMP, można przystąpić do kompilacji programów zawierających elementy zrównoleglania. Aby poinformować kompilator, że ma on do czynienia z programem wielowątkowym wystarczy w linii poleceń GCC dodać flagę -fopenmp, według następującego wzoru:

$ gcc -fopenmp kod_zrodlowy.c -o program_wynikowy

Dzięki tej fladze kompilator poprawnie zinterpretuje wszystkie dyrektywy OpenMP i wygeneruje kod wynikowy przystosowany do uruchamiania programu z użyciem wielu wątków. Jeśli jednak flaga -fopenmp zostanie pominięta, program skompiluje się bezproblemowo, ale zostanie pozbawiony możliwości działania wielowątkowego.

Poprawne zrównoleglenie programu nie może się także odbyć bez zadeklarowania w kodzie źródłowym biblioteki odpowiadającej za obsługę funkcji i dyrektyw OpenMP. Odbywa się to poprzez wstawienie następującego pliku nagłówkowego na początku programu:

#include < omp.h >


Uruchamianie programu wielowątkowego

Skompilowany program z elementami OpenMP można uruchomić na dwa sposoby. Pierwszym z nich jest klasyczne wywołanie programu bez żadnych dodatkowych parametrów w linii poleceń

$ ./moj_program

Tak uruchomiony program będzie zazwyczaj działał na tylu wątkach ile fizycznie procesorów/rdzeni możliwych jest do wykorzystania w danym komputerze2. Czyli, jeżeli pracujemy na maszynie dwurdzeniowej, program domyślnie zostanie uruchomiony dla dwóch wątków. Warto mieć jednak kontrolę nad ilością wątków biorących udział w przetwarzaniu danych. W tym celu wykorzystywana jest zmienna środowiskowa OMP_NUM_THREADS.

$ env OMP_NUM_THREADS=4 ./moj_program

Za pomocą powyższej konstrukcji, zmienna środowiskowa OMP_NUM_THREADS zyskała wartość 4, co znaczy, że program zostanie uruchomiony dla czterech wątków. Oczywiście w zależności od stopnia skomplikowania programu, nie wszystkie wątki muszą zostać użyte w czasie jego działania. Niekiedy zadanie obliczeniowe jest na tyle proste, że niektóre wątki w ogóle nie mają szansy rozpocząć przetwarzania danych. Dzieje się tak, ponieważ wątki o niższych numerach id, na tyle szybko przetwarzają dane, że kolejne nie zdołają nawet pobrać danych do przetwarzania.


1http://phase.hpcc.jp/Omni/Omni-doc/Install.html
2https://docs.loni.org/wiki/Using_OpenMP