PVM — Parallel Virtual Machine

Transkrypt

PVM — Parallel Virtual Machine
PVM — Parallel Virtual Machine
Sławomir ’civic’ Białek
<[email protected]>
22 września 2002 roku
Czym jest PVM?
PVM – Parallel Virtual Machine jest rozwiązaniem pozwalającym wykorzystać heterogeniczny kluster komputerów w funkcji pojedyńczego komputera równoległego.
Projekt PVM rozpoczął się w 1989 roku w Oak Ridge National Laboratory.
Stworzona tam wersja PVM 1.0 była jednak wykorzystywana tylko na ich wyłączne potrzeby. Wersja PVM 2 została napisana na University of Tennessee i
udostępniona w Marcu 1991 roku. PVM zaczęto wykorzystywać do rozwiązywania wielu naukowych problemów wymagających większej mocy obliczeniowej. W
lutym 1993 roku ujrzała światło dzienne po przepisaniu większości kodu wersja
PVM 3, rozwijana i używana do dziś (aktualne wersje to 3.4.x).
Programowanie współbieżne jest jedną z kluczowych technologii dla rozwiązywania dzisiejszych zadań wymgających dużych mocy obliczeniowych. Jednakże
koszty potężnych maszyn MPP (Massively Parallel Processors) często stwarzają
równie potężną barierę. I tutaj z pomocą przychodzą rozwiązania takiej jak PVM.
PVM pozwala zamienić heterogeniczny kluster komputerów, od najprostszych
klasy PC pracujących pod systemami operacyjnymi Windows, Linux, *BSD poprzez mniejsze i większe serwery Sun, IBM, HP, DEC i SGI do dużych komputerów
równoległych w wielki wirtualny komputer równoległy. Skomplikowane problemy
obliczeniowe mogą być dzięki temu rozwiązywane przy użyciu połączonej mocy
obliczeniowej wielu komputerów.
System PVM udostępnia użytkownikowi możliwość automatycznego uruchamiania procesów na maszynie wirtualnej, funkcji do ich komunikacji i synchornizacji. PVM w sposób przezroczysty dla programisty zajmuje się przekazywaniem
komunikatów, konwersją formatów danych oraz zarządzaniem zadaniami.
Na podkreślenie zasługuje fakt iż PVM jest oprogramowaniem dostępnym
za darmo. Tak więc nie tylko pozwala obniżyć koszty sprzętu, ale też sam jako
oprogramowanie nic nie kosztuje. Choć oczywiście istnieją firmy, które świadczą
komercyjny support lub zajmują się tworzeniem komercyjnego oprogramowania
wykorzystującego PVM.
Architektura PVM
PVM jest pakietem oprogramowania, który składa się głównie z dwóch elementów:
• demona – uruchamianego na komputerach, które stają się węzłami sieci
tworzącej wirtualny komputer równoległy
• biblioteki funkcji zawierającej interfejs dla programów mających działać z
PVM
Biblioteka funkcji wraz z demonem udostępniają programowi mechanizmy
przekazywania komunikatów, uruchamiania i synchronizacji zadań oraz możliwość
modyfikacji maszyny wirtualnej PVM. Wykorzystanie możliwości PVM dostępnie
jest głównie z języków C, C++ i Fortran bowiem to dla nich zostały przygotowane biblioteki. Aczkolwiek istnieją również pakiety pozwalające wykorzystać PVM
również w Javie, Perlu oraz Tcl/Tk, a także innych językach i technologiach.
Model programowania PVM zakłada, że aplikacja składa się z szeregu zadań.
Umożliwia to zastosowanie PVM zarówno poprzez dzielenie zadania na funkcjonalne podzadania, a także poprzez podział zadania na wiele równoległych zadań,
które zajmują się fragmentem danych wejściowych lub obie te metody równocześnie.
Z wyjątkiem wywoływania specyficznych dla PVM funkcji dotyczących np.
uruchamiania zadań czy przekazywania komunikatów i synchronizacji programy
pisze się w sposób nie wiele odbiegający od programowania bez PVM. Również
programista nie musi się przejmować tym na jakich i ilu komputerach (ale może
też mieć na to wpływ jeśli chce) zostanie cały proces uruchomiony, aplikacje pisze
tak jak dla jednego równoległego komputera. Resztą zajmuje się w/w biblioteka
wraz z demonem. Oczywiście liczba dostępnych komputerów nie musi i zwykle nie
jest równa liczbie zadań, które uruchomi program. W skrajnym przypadku cały
program składający się z wielu równoległych zadań może zostać uruchomiony na
maszynie wirtualnej PVM stworzonej na pojedyńczym komputerze.
Demon niezbędny w każdym węźle tworzącym część wirtualnego komputera
może zostać uruchomiony przez dowolnego użytkownika. Nie są wymagane żadne
specjalne uprawnienia. Komunikacja pomiędzy węzłami realizowana jest poprzez
datagramy UDP tak więc w warstwie sieciowej koniecznie jest zapewnienie możliwości przekazywania pakietów UDP pomiędzy węzłami sieci PVM (uwaga na
firewalle).
Zadania zarządzane przez system PVM są reprezentowane w PVM przez unikalny TID (ang. task identifier). PVM zawiera funkcje, które powodują iż proces
użytkownika staje się procesem maszyny wirtualnej PVM. PVM dostarcza funkcje do rozszerzania konfiguracji o nowe komputery jak i usuwania komputerów z
PVM, do uruchamiania i usuwania zadań, do wysyłania sygnałów do innych procesów PVM oraz do testowania stanu konfiguracji i aktywnych procesów PVM.
PVM pozwala także na organizację zadań w grupy, które mogą się zmieniać
dynamicznie podczas wykonania programu. Zadanie PVM może zostać dołączone lub może opuścić dowolną grupę w dowolnym momencie. Zadania należące
do grup mogą wysyłać komunikaty do zadań innych grup jak i mogą otrzymać
informację o innych zadaniach tej samej grupy. System PVM dostarcza specjal-
nej funkcji do wykonania zdefiniowanej przez użytkownika globalnej operacji na
danych obliczonych przez wszystkie zadania grupy. W celu synchronizacji zadań
tej samej grupy wprowadzono mechanizm blokowania wykonywania się zadań
poprzez tzw. bariery. Mechanizm ten polega na wstrzymaniu wykonania zadań
danej grupy (poprzez ustawienie bariery), aż do chwili ustawienia bariery przez
ostatnie z zadań tej grupy. Wtedy wszystkie zadania rozpoczynają dalszą pracę.
Zadania PVM mogą wysyłać również sygnały do innych zadań. Zadania mogą
otrzymywać informację o zdarzeniu poprzez przesłany komunikat wraz ze zdefiniowaną przez użytkownika etykietą, która będzie rozpoznawana przez aplikację.
Zdarzenia mogą również dotyczyć istnienia zadań, usunięcia (uszkodzenia) komputera z sieci oraz dodania nowego komputera.
PVM dostarcza stosownych funkcji do pakowania, rozpakowywania i wysyłania komunikatów. Każde zadanie może wysyłać komunikaty do dowolnych innych
zadań bez (teoretycznie) limitu na wielkość i ilość przesyłanych komunikatów.
Jednakże, ponieważ bufory komunikatów są alokowane dynamicznie to wielkość
komunikatu jaki może zostać wysłany lub odebrany zależy od wielkości dostępnej
wolnej pamięci komputera odpowiednio wysyłającego lub odbierającego.
Komunikat może zawierać wiele tablic, z których każda może zawierać dane
innego typu oraz nie ma ograniczeń na złożoność struktury pakowanych danych.
Natomiast aplikacja powinna rozpakowywać komunikat dokładnie w ten sam sposób w jaki był on pakowany aby utrzymać integralność danych. Funkcje PVM do
pakowania i rozpakowywania komunikatów obsługują wszystkie konieczne konwersje danych. Jednakże programista musi uważać na możliwość utraty dokładności w przypadku przesyłania danych np. z komputera 64-bitowego (CRAY)
na komputer 32-bitowy (SPARC station). Model komunikacji w systemie PVM
pozwala na asynchroniczne wysyłanie komunikatów, asynchroniczne blokowane i
nie blokowane odbieranie komunikatów oraz zawiera funkcję testującą przybycie
komunikatu bez jego odebrania. Dodatkowo PVM zawiera funkcję do wysyłania
komunikatów do wielu zadań jednocześnie, na przykład do zdefiniowanej przez
użytkownika grupy zadań.
Model PVM pozwala na naturalną wewnętrzną komunikację pomiędzy procesorami komputera wieloprocesorowego. Komunikaty pomiędzy procesorami są
przesyłane bezpośrednio, natomiast komunikaty od lub do komputera wieloprocesorowego są przesyłane poprzez sieć odpowiednio od lub do demona PVM-a.
Użytkownik dostaje do dyspozycji również konsolę systemu PVM (o nazwie
pvm), który umożliwia użytkownikowi interakcyjny sposób współpracy z maszyną wirtualną. Konsola może być uruchamiana wielokrotnie po skonfigurowaniu
PVM, na każdym z komputerów aktualnej konfiguracji. Można również, uruchomić konsolę bez wcześniejszego skonfigurowania PVM i wtedy proces konsoli
automatycznie uruchomi proces demona pvmd3 na tym samym komputerze.
Zastosowanie PVM
Ze względu na architekturę PVM, a także dostępność i koszty PVM można
wykorzystać m.in. jako:
• możliwość stworzenia taniego super komputera wykorzystującego wolne cykle (po ustawieniu odpowiedniego priorytetu) istniejących i wykonujących
inne funkcje komputerów
• możliwość taniego zwiększenia mocy obliczeniowej udostępnianiej pojedyńczemu programowi poprzez połączenie mocy więcej niż jednego komputera
• narzędzie edukacyjne do nauki programowania współbieżnego oraz do badań naukowych
Funkcje PVM
Większość możliwości PVM została już wspomniana we wcześniejszych punktach, jednak podsujmy jeszcze raz w uporządkowany sposób co oferuje PVM dla
użytkownika:
• Zarządzanie zasobami – możliwość dodawania i usuwania komputerów z
maszyny wirtualnej PVM. Należy podreślić, że z możliwości tej można
korzystać również w czasie pracy aplikacji i maszyny wirtualnej, oczywiście
bez szkody dla nich. Nie dość, że PVM umożliwia dość duże skalowanie
systemu poprzez dodawanie kolejnych maszyn to jeszcze można to robić
już w czasie działania aplikacji, zarówno w górę jak i w dół.
• Zarządzanie zadaniami – możliwość tworzenia, kończenia, a także zabijania zadań wchodzących w skład danego procesu/aplikacji. Przy tworzeniu
zadania można pozostawić PVM decyzję co do tego, na którym węźle zostanie uruchomione zadanie lub określić architekturę sprzętową na której
powinno zostać wykonane lub nawet wskazać konkretny węzeł sieci tworzącej maszynę wirtualną.
• Dynamiczne grupy zadań – umożliwiają grupowanie zadań i dostarczają
dodatkowych możliwości dla grupy: komunikatów rozsyłanych po członkach
grupy, mechanizmu synchronizacji grupy opartego o bariery (ang. barrier).
• Komunikacja – PVM umożliwia przekazywanie sygnałów oraz komunikatów
do innych zadań. W przypadku komunikatów, które mogą być dowolnymi
danymi PVM zapewnia funkcje do pakowania i rozpakowywania danych,
które to zapewniają odpowiednie konwersje danych pomiędzy różnymi architekturami sprzętowymi.
• Tolerancja uszkodzeń – PVM radzi sobie również z niezamierzoną rekonfiguracją wirtualnej maszyny, tzn. gdy któraś z maszyn przestanie prawidłowo pracować. Zadania pracujące na komputerze, który ulega awarii zostają
oczywiście stracone, ale nie wpływa to na zadania pracujące w pozostałych
węzłach, a także mogą być one o tym fakcie poinformowane co umożliwia
aplikacji podjęcie odpowiednich działań.
Programowanie z PVM
Ponieważ PVM nie jest zbyt skomplikowanym dla użytkownika - programisty systemem najprościej go poznać programując z nim. Napiszemy więc prosty
program w C korzystający z podstawowych możliwości PVM wprowadzając i
omawiając je kolejno.
Oczywiście każdy program korzystający z biblioteki libpvm musi zawierać włączenie pliku nagłówkowego zawierające deklaracje API biblioteki, czyli rozpoczynamy od: #include "pvm3.h".
Aby proces stał się procesem wirtualnej maszyny PVM powinien wywołać
funkcję pvm mytid() (choć podobny efekt spowoduje wywołanie każdej funkcji
libpvm to jednak dla porządku warto wywołać ją jawnie). Wszystkie funkcje PVM
sygnalizują błędy zwracająć ujemną wartość tak więc program powinien sprawdzić
czy operacja się powiodła. W przypadku powodzenia funkcja ta zwraca unikalny
TID zadania. Proces może zakończyć swoją współpracę z PVM wywołując funkcję
pvm exit().
Do uruchomienia równoległych zadań programista ma do dyspozycji funkcję pvm spawn(), która jako argumenty przyjmuję nazwę procesu do wykonania, parametry do przekazania, liczbę egzemplarzy zadania do uruchomienia oraz
opcjonalnie określenie na którym węźle bądź na jakiej architekturze uruchomić
zadanie. Funkcja zwraca ilość uruchomionych zadań oraz tablicę ich TIDów. Do
dyspozycji jest również funkcja pvm kill() pozwalająca wymusić zakończenie
zadania o konkretnym TID.
PVM udostępnia również szereg funkcji zwracających wiele informacji na temat stanu i konfiguracji maszyny wirtualnej oraz konkretnych zadań. Są to funkcje takie jak pvm parent(), pvm config(), pvm tasks() itp.
Przyjżyjmy się teraz sposobom na przekazywanie komunikatów. Jeżeli chcemy wysłać komunikat najpierw musimy wywołać funkcję inicjalizującą bufor oraz
sposób przesyłania. Służy do tego funkcja pvm initsend(). Następnie należy
„zapakować” dane do przesłania co zapewnia przy właściwym stosowaniu bez-
problemowe przesyłanie danych pomiędzy różnymi architekturami. Służą do tego
funkcje z rodziny pvm pack(), na przykład pvm packf() działająca w sposób
właściwy dla funkcji typu printf pozwalająca przesyłać jako ciąg różne typy danych. „Zapakowane” dane zostają umieszczone w buforze.
Wysłania danych oczekujących w buforze możemy dokonać na kilka sposobów. Jednym z nich jest wywołanie funkcji pvm send(), która pozwala przekazać
dane do procesu o konkretnym TID. Oprócz samej zawartości przy wysyłaniu komunikatu musimy określić tzw. etykietę komunikatu w postaci liczby całkowitej.
Etykiety powinno się używać do oznaczenia rodzaju komunikatu. Zadanie odbierające komunikaty może następnie wybierać jakie komunikaty chce w danej
chwili odebrać określając to właśnie poprzez tą etykietę. Może również dzięki
temu zastosować odpowiedni sposób obróbki odebranych danych, w tym - co
ważne - odpowiednią funkcję „rozpakowującą”, która oczywiście powinna być
konkretnym odpowiednikiem dla funkcji, którą użyto do „zapakowania” danych.
W przypadku potrzeby wysłania komunikatu do większej liczby zadań można użyć
funkcji pvm mcast(), która pozwala podać tablicę TIDów jako adresatów komunikatu lub pvm bcast(), która pozwala skierować komunikat do dowolnej grupy
procesów.
Zadanie gotowe do odbierania komunikatów mogą to zrobić wywołując funkcję pvm recv(), która odbiera komunikat od konkretnego lub dowolnego zadania
(wg TID) o konkretnej lub dowolnej etykiecie, ale zawsze blokując wykonanie programu do czasu aż nadajdzie określony komunikat. Dlatego też istnieje podobna
funkcja pvm trecv(), która jednakże pozwala na określenie czasu po którym
oczekiwanie na komunikat się zakończy. Do dyspozycji jest również całkiem nie
blokująca pvm nrecv(), która wraca zawsze od razu po wywołaniu bez względu
na to czy jest dostępny określony komunikat czy nie. W niektórych przypadkach
przydatna może być tez funkcja pvm probe(), która tylko sprawdza czy określony
(tak jak we wszystkich funkcjach odbierających wg TID lub etykiety komunikatu)
komunikat jest dostępny.
Po odebraniu komunikatu jak już to było wspomniane należy wykonać odpowiednią funkcję „rozpakowującą” dane. Służą do tego funkcje z rodziny pvm unpack().
Wyposażeni w tą podstawową wiedzę możemy stworzyć już pierwszy program
równoległy składający się z dwóch procesów. Pierwszy najpierw wywoła drugie
zadanie potomne uruchamiając drugi proces, a następnie będzie oczekiwał na
dowolny komunikat, który następnie wypisze na ekranie (zakładamy, że będzie
to komunikat tekstowy). Drugie zadanie wyśle do swojego procesu - rodzica
komunikat tekstowy.
/ ∗ ex1 . c ∗ /
#i n c l u d e < s t d i o . h>
#i n c l u d e ”pvm3 . h”
main ( )
{
i n t cc , t i d ;
char b u f [ 2 5 5 ] ;
p r i n t f ( ” mój TID: % x \n” , pvm mytid ( ) ) ;
c c = pvm spawn ( ” e x 1 s u b ” , ( char ∗ ∗ ) 0 , 0 , ”” , 1 , & t i d ) ;
i f ( cc > 0) {
cc = pvm recv (−1, −1);
pvm bufinfo ( cc , ( i n t ∗ ) 0 , ( i n t ∗)0, & t i d ) ;
pvm upkstr ( buf ) ;
p r i n t f ( ” k o m u n i k a t od %x : % s \n” , t i d , b u f ) ;
} else
p r i n t f ( ” w y s t ą p i ł b ł ą d p r z y p r ó b i e u r u c h o m i e n i a e x 1 s u b \n” ) ;
pvm exit ( ) ;
exit (0);
}
/∗ ex1 sub . c ∗/
#i n c l u d e ”pvm3 . h”
main ( )
{
int ptid ;
char b u f [ 2 5 5 ] ;
p t i d = pvm parent ( ) ;
s t r c p y ( b u f , ” k o m u n i k a t t e k s t o w y od e x 1 s u b ” ) ;
p v m i n i t s e n d ( PvmDataDefault ) ;
pvm pkstr ( buf ) ;
pvm send ( p t i d , 1 ) ;
pvm exit ( ) ;
exit (0);
}
Przykład jest dość prosty ale pokazuje jak działają dwie z ważniejszych funkcji PVM - uruchamianie zadań oraz przekazywanie komunikatów. Przyjżyjmy się
jeszcze jednemu przykładowi, który co prawda używa prawie tych samych funkcji
PVM jednak prezentuje jeden z paradygmatów programów równoległych zwany
często „master-slave”. Polega on na tym, że jeden z procesów (zazwyczaj ten
pierwszy uruchamiany na początku) zajmuje się kontrolowaniem całego przebiegu aplikacji. Uruchamia równoległe zadania, inicjalizuje je, przekazuje im dane
i odbiera wyniki, podejmuje odpowiednie akcje w sytuacjach szczególnych. Poniższy program, również podzielony na dwa zadania - master i slave, w części
master, która powinna być uruchomiona przez użytkownika stara się uruchomić
trzy razy więcej procesów slave niż jest węzłów tworzących wirtualną maszynę
PVM (jednak nie więcej niż 32). Jeżeli operacja się powiedzie wysyła przygotowaną procję danych do wszystkich utworzonych procesów, a następnie oczekuje
od każdego z nich na odpowiedź. Procesy slave odbierają komunikat z porcją
danych, następnie wykonują na nich pewną operację podczas której komunikują
się z innymi procesami slave i wreszcie wysyłają wyniki do procesu master.
/∗ master . c ∗/
#i n c l u d e < s t d i o . h>
#i n c l u d e ”pvm3 . h”
main ( )
{
i n t mytid ;
/ ∗ TID ∗ /
int tids [ 3 2 ] ;
/∗ s l a v e task i d s ∗/
i n t n , n p r o c , numt , i , who , msgtype , n h o s t , n a r c h ;
f l o a t data [ 1 0 0 ] , r e s u l t [ 3 2 ] ;
struct pvmhostinfo ∗ hostp ;
m y t i d = pvm mytid ( ) ;
pvm config ( & nhost , & narch , & hostp ) ;
nproc = nhost ∗ 3 ;
i f ( nproc > 32 ) nproc = 32 ;
p r i n t f ( ” Uruchamiam %d zadań . ” , n p r o c ) ;
numt=pvm spawn ( ” s l a v e ” , ( char ∗ ∗ ) 0 , 0 , ”” , n p r o c , t i d s ) ;
i f ( numt < n p r o c ) {
p r i n t f ( ”\ n Błąd p r z y u r u c h a m i a n i u s l a v e : \ n” ) ;
f o r ( i=numt ; i<n p r o c ; i ++ ) {
p r i n t f ( ”TID %d %d\n” , i , t i d s [ i ] ) ;
}
f o r ( i = 0 ; i<numt ; i ++ ){
pvm kill ( tids [ i ] ) ;
}
pvm exit ( ) ;
exit (1);
}
p r i n t f ( ”SUCCESSFUL\n” ) ;
/ ∗ B e g i n U s e r Program ∗ /
n = 100;
f o r ( i = 0 ; i<n ; i ++ ){
data [ i ] = 1 . 0 ;
}
/ ∗ W y s ł a n i e k om uni k atu z danymi do u t w o r z o n y c h p r o c e s ó w ∗ /
p v m i n i t s e n d ( PvmDataDefault ) ;
p v m p k i n t (& n p r o c , 1 , 1 ) ;
pvm pkint ( t i d s , nproc , 1 ) ;
p v m p k i n t (&n , 1 , 1 ) ;
pvm pkfloat ( data , n , 1 ) ;
pvm mcast ( t i d s , n p r o c , 0 ) ;
/ ∗ O c z e k i w a n i e na w y n i k i ∗ /
msgtype = 5 ;
f o r ( i = 0 ; i<n p r o c ; i ++ ){
p v m r e c v ( − 1 , msgtype ) ;
p v m u p k i n t ( & who , 1 , 1 ) ;
p v m u p k f l o a t ( & r e s u l t [ who ] , 1 , 1 ) ;
p r i n t f ( ” Odebrałem % f od %d ; ” , r e s u l t [ who ] , who ) ;
i f ( who == 0)
p r i n t f ( ” ( s p o d z i e w a n o % f ) \ n” , ( n p r o c − 1 ) ∗ 1 0 0 . 0 ) ;
else
p r i n t f ( ” ( s p o d z i e w a n o % f ) \ n” , ( 2 ∗ who − 1 ) ∗ 1 0 0 . 0
}
/ ∗ o d ł ą c z e n i e od PVM ∗ /
pvm exit ( ) ;
}
/∗ s l a v e . c ∗/
#i n c l u d e < s t d i o . h>
#i n c l u d e ”pvm3 . h”
main ( )
{
i n t mytid ;
/ ∗ TID ∗ /
int tids [ 3 2 ] ;
/∗ task i d s
∗/
i n t n , me , i , n p r o c , m a s t e r , msgtype ;
f l o a t data [ 1 0 0 ] , r e s u l t ;
f l o a t work ( ) ;
m y t i d = pvm mytid ( ) ;
/ ∗ O d e b r a n i e danych od m a s t e r ∗ /
msgtype = 0 ;
p v m r e c v ( − 1 , msgtype ) ;
p v m u p k i n t (& n p r o c , 1 , 1 ) ;
pvm upkint ( t i d s , nproc , 1 ) ;
p v m u p k i n t (&n , 1 , 1 ) ;
pvm upkfloat ( data , n , 1 ) ;
/ ∗ którym p r o c e s e m j e s t e m ? ∗ /
f o r ( i = 0 ; i<n p r o c ; i ++ )
i f ( m y t i d == t i d s [ i ] ) { me = i ; break ; }
/ ∗ w y k o n a n i e o b l i c z e ń na danych ∗ /
r e s u l t = work ( me , n , d a t a , t i d s , n p r o c ) ;
/ ∗ w y s ł a n i e wyników ∗ /
p v m i n i t s e n d ( PvmDataDefault ) ;
p v m p k i n t ( &me , 1 , 1 ) ;
pvm pkfloat ( & r e s u l t , 1 , 1 ) ;
msgtype = 5 ;
master = pvm parent ( ) ;
pvm send ( m a s t e r , msgtype ) ;
/ ∗ o d ł ą c z e n i e od PVM ∗ /
pvm exit ( ) ;
}
f l o a t work ( i n t me , i n t n , f l o a t ∗ d a t a , i n t ∗ t i d s , i n t n p r o c )
{
int i , dest ;
f l o a t psum = 0 . 0 ;
f l o a t sum = 0 . 0 ;
f o r ( i = 0 ; i<n ; i ++ ){
sum += me ∗ d a t a [ i ] ;
}
/∗ komunikacja z sąsiednim s l a v e ∗/
p v m i n i t s e n d ( PvmDataDefault ) ;
p v m p k f l o a t ( & sum , 1 , 1 ) ;
d e s t = me+1;
i f ( d e s t == n p r o c ) d e s t = 0 ;
pvm send ( t i d s [ d e s t ] , 2 2 ) ;
pvm recv ( − 1 , 2 2 ) ;
p v m u p k f l o a t ( & psum , 1 , 1 ) ;
r e t u r n ( sum+psum ) ;
}
Zakończenie
Nieniejsze opracowanie zawiera zwięzły wstęp w świat programowania równoległego z PVM. Pokazuje do czego służy, co z PVM można osiągnąć oraz na
kilku przykładach prezentuje jak szybko zacząć programować z PVM. Jednakże ze
względu na ograniczony czas, który mógł zostać poświęcony temu opracowaniu
nie omawia wszystkich tematów wystarczająco szeroko, niektóre takie jak obsługa we/wy, debugowanie, dodatkowe aplikacje wspomagające, bezpieczeństwo
danych i programów pomija. Dlatego też zainteresowanego programowaniem z
PVM czytelnika odsyłam do umieszczonego na końcu spisu literatury w celu
uzupełnienia brakujących informacji.
Spis literatury
[1] Al Geist, Adam Begeuelin, Jack Dongarra, Weicheng Jiang, Robert Manchek, Vaidy Sunderam. PVM: Parallel Virtual Machine, A Users’ Guide and
Tutorial for Networked Parallel Computing. The MIT Press. 1994.
[2] PVM Home Page – http://www.epm.ornl.gov/pvm/pvm_home.html
[3] An Introduction to PVM Programming – http://www.epm.ornl.gov/
pvm/intro.html
[4] Obliczenia i programowanie równoległe – http://k2.pcz.czest.pl/
~roman/mat_dyd/prz_rown/prz_rown.html
[5] Dokumentacja i przykłady dostarczane z pakietem PVM
12

Podobne dokumenty