mpich

Transkrypt

mpich
Programowanie Współbieżne
MPI
( główne źródło http://pl.wikipedia.org/wiki/MPI)
1
Historia
●
●
Początkowo (lata 80) różne środowiska przesyłania
komunikatów dla potrzeb programowania równoległego.
Niektóre wyspecjalizowane na konkretne maszyny np. Caltech
N-cube.
●
Niektóre rozwijane dla sieci UNIX – workstation
●
Np. PVM, Argonne's, P4, PICL
●
●
Ohio Supercomputer Center opublikował standard przesyłania
komunikatów LAM (pakiet specjalnie przystosowany do
obliczeń w chemii kwantowej) zwany później TCGMSG
Ta sama firma wypuściła komercyjny pakiet Express
przeznaczony dla N-cube
2
Historia
Początkowo różne rozwiązania dublowały się.
●
●
Październik 1992 – na konferencji Supercomputing 92
porozumiano się w sprawie opracowania wspólnego standardu
przesyłania komunikatów i wtedy powstał MPI.
Kilka bibliotek nie pasowała do sztywnych standardów np. ISIS
ale weszły one do systemu klastrowego Microsoftu zwanego
Wolfpack. ISIS bazował na idei wirtualnego synchronizowania
procesów i nie nadawał się w zastosowaniach naukowych i
komercyjnych ze względu na zbyt duże obciążenie.
●
W MPI synchronizacja nie była wymogiem krytycznym.
●
Pierwszy standard MPI 1 był gotowy w maju 1994
●
Drugi MPI 2 ukończono w 1998 roku
3
●
Historia
MPI-2 nie zdobył zbyt wielkiej popularności gdyż w 1997 roku
wprowadzono MPICH zawierający część poprawek
wprowadzonych w MPI-2
●
●
●
●
MPICH i LAM to dwie najczęstsze implementacje standardu
MPI
Powstały też wyspecjalizowane implementacje np. Firma SGI
wprowadziła na swoje platformy MPT (Message Passing
Toolkit)
Od 1998 wprowadzano jeszcze przez 4 lata różne korekty by w
2002 wyszła pierwsza zaawansowana implementacja.
W MPI-2 zdefiniowano równoległe operacje wejścia wyjścia
które pierwotnie zostały zawarte w pakiecie MPI-IO rozwijanym
specjalnie na potrzeby NASA, a następnie zmodyfikowane i
przeniesione do nowego MPI-2.
4
Cechy
●
●
●
●
MPI jest specyfikacją biblioteki funkcji opartych na modelu
wymiany komunikatów dla potrzeb programowania
równoległego.
Transfer danych pomiędzy poszczególnymi procesami programu
wykonywanymi na procesorach maszyn będących węzłami
klastra odbywa się za pośrednictwem sieci.
Program w MPI składa się z niezależnych procesów operujących
na różnych danych (MIMD).
Każdy proces wykonuje się we własnej przestrzeni adresowej,
aczkolwiek wykorzystanie pamięci współdzielonej też jest
możliwe.
5
Cechy
●
●
●
●
Główną zaletą standardu jest przenośność.
Udostępnia on zbiór precyzyjnie zdefiniowanych metod,
które mogą być efektywnie zaimplementowane.
Stał się on punktem wyjściowym do stworzenia
praktycznego, przenośnego, elastycznego i efektywnego
narzędzia do przesyłania komunikatów (ang. message
passing).
Standard MPI pozwala na jego zastosowanie zarówno w
komputerach równoległych, jak i heterogenicznych
sieciach stacji roboczych.
6
Cechy
●
●
●
Standard nie zabrania, aby poszczególne procesy były
wielowątkowe.
Nie są też udostępnione mechanizmy związane z
–
rozłożeniem obciążenia pomiędzy poszczególne
procesy,
–
z architekturą rozkładu procesorów,
–
z dynamicznym tworzeniem i usuwaniem procesów.
Procesy są identyfikowane poprzez ich numer w grupie w
zakresie 0 .. groupsize - 1.
7
Cechy
Główne własności MPI
●
●
●
●
●
●
umożliwia efektywną komunikację bez obciążania procesora
operacjami kopiowania pamięci,
udostępnia funkcje dla języków C/C++, Fortan oraz Ada,
specyfikacja udostępnia hermetyczny interfejs programistyczny,
co pozwala na skupienie się na samej komunikacji, bez
wnikania w szczegóły implementacji biblioteki i obsługi błędów,
definiowany interfejs zbliżony do standardów takich jak: PVM,
NX czy Express,
udostępnia mechanizmy komunikacji punkt - punkt oraz
grupowej,
może być używany na wielu platformach, tak równoległych jak i
skalarnych, bez większych zmian w sposobie działania.
8
Cechy
Zalety MPI
●
dobra efektywność w systemach wieloprocesorowych,
●
dobra dokumentacja,
●
bogata biblioteka funkcji,
●
posiada status public domain,
●
przyjął się jako standard.
9
Cechy
Wady MPI
●
●
●
statyczna konfiguracja jednostek przetwarzających,
statyczna struktura procesów w trakcie realizacji programu
(dotyczy to implementacji opartych o MPI-1). Wersja MPI-2
(wspierana np przez LAM 7.0.4) umożliwia dynamiczne
zarządzanie strukturą procesów biorących udział w
obliczeniach - MPI_Spawn(),
brak wielowątkowości.
10
OpenMP
●
●
Jest specyfikacją dyrektyw kompilatora, bibliotek i
zmiennych środowiskowych na potrzeby przetwarzania
współbieżnego w Fortranie i C/C++ opartego o mechanizm
pamięci współdzielonej oraz wątki. Zaprojektowany przez
głównych twórców sprzętu i oprogramowania zapewnia
przenośne i skalowalne wspólne API dla różnych platform
sprzętowych i programowych
Ideą OpenMP jest stworzenie prostego mechanizmu
wspierającego programowanie wielowątkowe, bez
konieczności posiadania szczegółowej wiedzy o tworzeniu,
synchronizacji i niszczeniu wątków. Zamiast tego
programista otrzymuje możliwość bezpośredniego
określania, które partie programu i jak mają być wykonane.
11
OpenMP
Przykładowy program „Hello World”
#include <omp.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
int id, nthreads;
#pragma omp parallel
private(id)
{
id = omp_get_thread_num();
printf("Hello World from thread %d\n", id);
#pragma omp barrier
if ( id == 0 )
{
nthreads = omp_get_num_threads();
printf("There are %d threads\n",nthreads);
}
}
}
12
OpenMP
Przykład kompilacji dla c++ intela.
$ icc -openmp program.cpp -o program
Uruchomienie programu dla czterech wątków:
$ env OMP_NUM_THREADS=4 ./program
OpenMP jest wspierany przez kompilator GCC od wersji 4.2
.
13
MPICH
●
●
●
●
●
ogólnodostępna, darmowa i przenośna implementacja
standardu MPI. Pozwala na przekazywanie komunikatów
pomiędzy aplikacjami działającymi równolegle. Nadaje się
do stosowania na małych klastrach.
Najnowszą wersję biblioteki MPICH można pobrać ze
strony domowej projektu.
Biblioteki MPICH można używać zarówno na systemach
klasy MS Windows jak i Unix.
Rozwinięciem MPICH jest MPICH2
Powstała także wersja tej biblioteki o nazwie MPICH-G2
pozwalająca uruchamiać aplikacje równoległe w
środowiskach gridowych, z wykorzystaniem pakietu lobus
Toolkit jako warstwy pośredniej. Dzięki temu rozwiązaniu
aplikacja może działać na kilku klastrach rozproszonych 14
geograficznie.
MPICH
●
Najnowsza wersja biblioteki MPICH2 poza bardziej
wydajnymi mechanizmami komunikacji posiada dodatkowo
–
Wsparcie dla komunikacji jednostronnej
–
Rozszerzoną funkcjonalność MPI-IO
15
MPICH
Instalacja
●
●
●
●
●
należy pobrać źródła programu : mpich.tar.gz
Rozpakowujemy plik mpich.tar.gz
# tar xfz mpich.tar.gz
Będąc w katalogu /mpich wydajemy komendę:
# ./configure --prefix=/opt/mpich
--prefix=/opt/mpich - określa ścieżkę docelową dla MPICH
Kompilujemy program wydając komendę:
# make
Dokonujemy instalacji w katalogu podanym w opcji prefix:
# make install
16
MPICH
Konfiguracja
●
W pliku machines.LINUX (katalog: /opt/mpich/share lub
inny wybrany w opcji prefix podczas instalacji) dopisujemy
nazwy hostów wchodzacych w skład klastra:
hostname1:liczba_procesów
hostname2:liczba_procesów
hostname3:liczba_procesów
gdzie:
●
●
hostname - oznacza nazwa komputera wchodzącego w
skład klastra,
liczba_procesów - liczba procesorów danego hosta
17
MPICH
Przykład komunikacji Punkt-Punkt.
●
●
Zadaniem programu jest przesłanie komunikatu o treści
"Komunikat od procesu 0" z procesu o numerze rank = 0
(SOURCE) do procesu o numerze rank = 1 (DEST).
Program kompiluje się wprowadzając polecenie:
# mpicc -o program_mpi program_mpi.c
#include <stdio.h>
#include "mpi.h"
#define TAG 0
#define COUNT 23
#define SOURCE 0
#define DEST 1
int main(int argc, char *argv[])
{
int rank, size;
MPI_Status status;
char Msg[]="Komunikat od procesu 0";
procesami
char Recv[COUNT];
// treść komunikatu przesyłanego między
18
MPICH
MPI_Init(&argc,&argv);
// inicjalizacja środowiska MPI
MPI_Comm_size(MPI_COMM_WORLD,&size); // ilość procesów w grupie zapisywana jest w
zmiennej size
MPI_Comm_rank(MPI_COMM_WORLD,&rank); // rank bieżącego procesu zapisywany jest w zmiennej
rank
if (size > 1) {
// sprawdzane jest czy istnieje minimalna liczba
procesów
// Komunikat przesyłany jest od procesu o numerze rank = 0 (SOURCE)
// do procesu o numerze rank = 1 (DEST)
if (rank == DEST) // jeżeli procesem jest proces odbierajacy komunikat:
{
printf ("process %d of %d waiting for message from %d\n", rank, size, SOURCE);
// odbiór komunkatu i zapis zawartości do bufora Recv
MPI_Recv(Recv, COUNT, MPI_CHAR, SOURCE, TAG, MPI_COMM_WORLD, &status);
printf ("process %d of %d has received: '%s'\n", rank, size, Recv);
}
else
if (rank == SOURCE) // jeżeli procesem jest proces nadający komunikat:
{
printf ("process %d of %d sending '%s' to %d\n", rank, size, Msg, DEST);
// wysyłanie komunkatu zawartego w buforze Msg
MPI_Send(Msg, COUNT, MPI_CHAR, DEST, TAG, MPI_COMM_WORLD);
}
}
MPI_Finalize();
return 0;
}
// zakończenie wykonywania procesów MPI
19
MPICH
Komunikacja grupowa
●
MPICH dostarcza kilku funkcji, ułatwiających
komunikowanie się "na raz", ze wszystkimi procesami w
grupie. Poza sporym ułatwieniem zapewniają one (a raczej
zapewnia to MPICH) ,że dane zostaną przesłane w
optymalny sposób (naiwny broadcast(iteracja) vs.
MPI_Bcast(algorytm "drzewiasty") ).
20
MPICH
MPI_Bcast Rozsyła komunikat do wszystkich procesów w
grupie.
int vsize = 4;
float vect[vsize];
...
int status = MPI_Bcast( vect ,vsize
,MPI_FLOAT ,0 /*root*/ ,
MPI_COMM_WORLD);
21
MPICH
MPI_Scatter Funkcja dzieli wektor danych wejściowych (w
procesie oznaczonym jako root) i rozsyła je tak ,że
procesowi o randze N jest przesyłana N-ta część wektora
danych.
int vsize = 4;
float matrix[vsize*vsize];
float rvect[vsize]
int status = MPI_Scatter(matrix,
vsize, MPI_FLOAT, rvect, vsize,
MPI_FLOAT, 0 /*root*/,
MPI_COMM_WORLD); // do 4-ech procesów
22
MPICH
MPI_Gather Funkcja odwrotna do MPI_Scatter. Zbiera dane
w procesie oznaczonym root. Ustawia je w kolejkę zgodnie
z rangą nadsyłającego procesu.
int vsize = 4;
float matrix[vsize*vsize];
float rvect[vsize]
int status = MPI_Gather(rvect, vsize,
MPI_FLOAT, matrix, vsize, MPI_FLOAT,
0 /*root*/ ,MPI_COMM_WORLD); // od 4ech procesów
23
MPICH
MPI_Reduce Funkcja wykonuje zdefiniowaną operację na
wysłanych przez procesy danych. Możliwe operacje:
●
●
●
●
●
●
●
●
●
●
MPI_MAX - maximum
MPI_MIN - minimum
MPI_SUM - suma
MPI_PROD - produkt
MPI_LAND - logiczny AND
MPI_LOR - logiczny OR
MPI_LXOR - logiczny XOR
MPI_BAND - bitowy AND
MPI_BOR - bitowy OR
MPI_BXOR - bitowy XOR
int val = 1, procCnt;
int status = MPI_Reduce( &val ,&procCnt ,1 ,MPI_INT ,MPI_SUM ,0 /*root*/
,MPI_COMM_WORLD ); // alternatywna metoda liczenia procesów
24
MPICH
●
●
Przykład komunikacji grupowej realizowanej za
pośrednictwem funkcji MPI_Scatter i MPI_Reduce.
Działanie programu polega na rozesłaniu poszczególnych
wierszy macierzy zawartej w buforze sendbuf do czterech
procesów w grupie.
Program kompiluje się wprowadzając polecenie:
# mpicc -o program_mpi program_mpi.c
25
#include "mpi.h"
#include <stdio.h>
#define SIZE 4
main(int argc, char *argv[])
{
int numtasks, rank, sendcount, recvcount, source;
float sendbuf[SIZE][SIZE] = {
{1.0, 2.0, 3.0, 4.0},
{5.0, 6.0, 7.0, 8.0},
{9.0, 10.0, 11.0, 12.0},
{13.0, 14.0, 15.0, 16.0} };
// inicjalizacja bufora do wysyłki
float recvbuf[SIZE];
MPI_Init(&argc,&argv);
// inicjalizacja środowiska MPI
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// rank bieżącego procesu zapisywany jest w
zmienej rank
MPI_Comm_size(MPI_COMM_WORLD, &numtasks); // ilość procesów w grupie zapisywana jest w
zmiennej size
if (numtasks == SIZE) {
// jeżeli w grupie są dokładnie 4 procesy:
source = 1;
sendcount = SIZE;
recvcount = SIZE;
// rozsyłanie do procesów w grupie komunikatu zawartego w buforze sendbuf
MPI_Scatter(sendbuf,sendcount,MPI_FLOAT,recvbuf,recvcount,
MPI_FLOAT,source,MPI_COMM_WORLD);
printf("rank= %d Results: %f %f %f %f\n",rank,recvbuf[0], recvbuf[1], recvbuf[2],
recvbuf[3]);
int val = 1, procCnt;
MPI_Reduce( &val ,&procCnt ,1 ,MPI_INT ,MPI_SUM ,source ,MPI_COMM_WORLD ); // suma
,czyli liczba procesów
}
else
printf("Must specify %d processors. Terminating.\n",SIZE);
MPI_Finalize(); // zakończenie wykonywania procesów MPI
26
}
MPICH
●
Więcej informacji
–
http://www-unix.mcs.anl.gov/mpi/mpich/ Strona
domowa projektu
–
http://www-unix.mcs.anl.gov/mpi/www/ Manual do
funkcji
27