LAM/MPI - czyli jak zbudować superkomputer
Zaczynamy kolejnego "czylijaka".
Często zdumiewał mnie fakt, iż "darmowe" oprogramowanie ogólnie nazywane Open Source (min. na licencjach BSD, GPL, LGPL, itd.) oferuje użytkownikom bardzo zaawansowane technologie. Chciałbyś zamienić swój stary 386 lub 486 na router? Nie ma sprawy, potrzebujesz tylko stacji dyskietek i 10MB RAMu, nie potrzeba dysku twardego. A pomogą takie projekty jak ClosedBSD, Linux Polopiryn, theWall i wiele innych. Chciałbyś mieć podręczny system na CD-ROMie? Zajrzyj na stronę LiveCD. Oto kilka dalszych przykładów:
- Apache - jeden z najpopularniejszych serwerów WWW.
- GRASS - system informacji przestrzennej/geograficznej, potężna baza danych GIS.
- GIMP - program do obróbki zdjęć i grafiki rastrowej porównywalny z PhotoShopem.
- XFree86 i KDE, GNOME - środowisko graficzne (nie mylić z nakładkami) i menadżery okien.
itd.. (resztę dopiszcie sobie sami).
I wreszcie chciałbyś mieć superkomputer lub klaster po minimalnych kosztach? Polecam:
Zacznijmy od krótkiego i powierzchownego wprowadzenia w świat klastrów. Klaster to grupa niezależnych komputerów (często wieloprocesorowych) połączona zazwyczaj szybką siecią w celu przetworzenia wspólnie tego samego problemu lub udostępniania tej samej usługi/zasobu. Może to być kompilacja programu; symulacja kształtu 3D nowych cząsteczek organicznych; szukanie cywilizacji pozaziemskiej w sygnałach radiowych (SETI@home, tzw. przetwarzanie rozproszone); symulacja zderzenia 2 gwiazd neutronowych po to aby zgłębić naturę hipotetycznych fal grawitacyjnych; itd. Oczywiście tak złożony problem jak ten ostatni, wymagał połączenia aż 3 potężnych ośrodków obliczeniowych w różnych częściach świata. I na pewno nie ma tutaj mowy o jakiś PCetach. I na koniec warto wspomnieć o możliwości łączenia kilku klastrów w jeden większy, tzw. metaklastry (klastry klastrów)
Rozróżnić można klika głównych podgrup:
- klastry naukowe - przetwarzanie równoległe, programowanie równoległe, cały zespół komputerów pracuje nad tym samym problemem, dużo tańsza alternatywa dla superkomputerów i "różnej maści Cray'ów" (parallel computing clusters);
- klastry balansujące zasobami serwerów - zespół serwerów, który udostępnia tę samą usługę lub zasób, w celu rozłożenia obciążenia spowodowanego dużą ilością klientów połączonych w tym samym czasie, serwery odsyłają zapytania pomiędzy siebie aby na każdym z nich było jednakowe obciążenie, w ten sposób można przyjąć bardzo duże ilości odległych klientów, np. strona WWW odwiedzana około milion razy na dzień (load ng clusters);
- klastry wysokiej niezawodności - zespół serwerów, które przejmują zadania od siebie w przypadku awarii jednego z nich, po to aby serwis jaki udostępniają był dostępny bez przestojów (high availability clusters).
Weźmy teraz pod uwagę szybki postęp technologiczny w przemyśle procesorów, pamięci czy sprzętu sieciowego. Okazuje się, że PCet ze środkowej półki posiada już wydajność dochodzącą do 1 Gflps (a nawet ją przekracza, 1 gigaflops = 1 miliard operacji zmiennoprzecinkowych w ciągu jednej sekundy). Czy można zatem pokusić się o zbudowanie klastra o wydajności kilku gigaflopsów? Oczywiście, że tak. Dodatkowym argumentem in plus będzie koszt całego przedsięwzięcia. Każdy klaster musi posiadać co najmniej jeden serwer - węzeł (master - node), który zarządza/monitoruje całym klastrem i co najmniej jeden węzeł podległy (slave - node). Oczywiście im więcej "niewolników" tym lepiej ;). Tylko serwer zarządzający musi posiadać takie "wodotryski" jak: monitor, kartę wideo, klawiaturę, mysz, stacje dyskietek, CD-ROM itp. W skrajnych przypadkach slave - nodes mogą nie posiadać dysków twardych, system jest pobierany z innego serwera na którym udostępnia się przestrzeń dyskową poprzez NFS, a demon dhcpd "podpowiada" jak dany węzeł się nazywa i jaki posiada numer IP. Ogólna zasada brzmi tak: "im głupszy węzeł tym lepiej". W rozwiązaniu tego problemu pomogą wam strony: www.freebsd.com.pl i www.freebsd.org.pl, podrozdziały o bezdyskowych terminalach. Można również udostępnić tylko część systemu z serwera plików i oprogramowania, np. cały katalog /usr lub /usr/local. Co zainstalujesz na serwerze plików, będziesz miał bez rejestracji na wszystkich węzłach. Możemy tutaj spotkać się z takim problemem jak przeciążenie sieci i serwera plików zbyt dużą liczbą klientów. Rozwiązaniem będzie wtedy zainstalowanie szybszej sieci (np. Gigabitowej) lub zwiększenie ilości serwerów plików. Wszystko zależy od tego ile będziemy mieli węzłów. Jeśli będzie ich tylko kilka, to serwer zarządzający może także być serwerem plików, routerem z włączoną usługę NAT (bo właśnie zamierzamy podłączyć nasz klaster do Internetu), itp.
Teraz weźmy "na tapetę" sieć. Minimalne wymagania to 100Mbps i switch. Ale wszystko zależy od zadania i oprogramowania jakie będziemy przetwarzali i stosowali. Okazuje się, że czasem lepiej posiadać dużą liczbę węzłów na wolniejszej sieci, niż kilka mocnych maszyn z szybkim ethernetem. Jeśli nasza sieć jest wąskim gardłem dla przetwarzania równoległego możemy zainstalować inne technologie sieciowe (Myrinet, Gigabit Ethernet, ATM, Fast Ethernet, FDDI, HIPPI ) lub pokombinować z topologią sieci (wersja dla biednych :)). Każdy węzeł posiada kilka kart sieciowych. W schemacie będzie to wyglądało jak sieć o kwadratowych "oczkach". Na każdym przecięciu linii będzie znajdował się węzeł. "Wewnętrzne" węzły będą posiadały 4 karty sieciowe aby połączyć się z 4 sąsiednimi węzłami a skrajne tylko 3. Jeśli tylko starczy slotów na karty rozszerzeń, możemy stworzyć trójwymiarową topologię sieci. Czyli "wewnętrzne" węzły będą posiadać 6 interfejsów sieciowych i na przykład 7 karta podłączona do switcha z serwerem zarządzającym i monitorującym. No dobrze, już dosyć tych fantazji. Na pewno będzie tyle pomysłów i modyfikacji co czytelników tego artykułu.
Procesory i pamięć. Dużo, dużo pamięci, to zawsze pomaga (ale znam systemy. którym nawet dużo pamięci zbytnio nie pomoże ;)). CPU im lepsze - tym nasza moc klastra będzie potężniejsza. Pofantazjujmy. Klaster złożony z 20 maszyn, każda CPU na 2GHz, z 512MB RAMu i Gigabitową siecią. Teoretycznie jego moc to 40Gflps!! Ale jeśli posiadacie dużą liczbę starych komputerów, które "gniją" w piwnicy, zastanówcie się i zajrzyjcie tutaj, znajdziecie tam opis klastra gdzie liczba węzłów wynosi ponad 130 komputerów, a ponad połowa z nich to 486. Jaki typ CPU? Na różnych stronach widziałem naprawdę wiele różnych typów: Intel, AMD, PA-Risk, Alpha, SPARC. Najważniejsze aby nasz system był stabilny. Bez wytykania palcem, do poważnych zastosowań nie polecam "gorących" procesorów, które mają problemy z chłodzeniem. Chociaż wielu z was za najważniejszą cechę uważa stosunek wydajności do ceny.
Teraz przyjrzyjmy się oprogramowaniu. Mamy do wyboru naprawdę sporą gamę aplikacji klastrowych. Monitorujące; zarządzające: i typowe przetwarzanie równoległe: . W naszym przypadku wykorzystamy LAM/MPI (Local Area Multicomputer), który wykorzystuje do komunikacji pomiędzy procesorami technologię MPI (Message Passing Interface ), kod źródłowy jest w 100% "portable", tzn. można go przenieść na różne platformy sprzętowe i systemowe. Teraz dodać opis 1 typu klastrów wymieniony wyżej i już wiemy z czym mamy do czynienia. Na wielu stronach. których linki znajdują się w tym artykule możecie znaleźć o wiele więcej szczegółowych informacji dotyczących technologii klastrowych, zachęcam do studiowania. Moim skromnym zdaniem, jest to dziedzina, która w Polsce czeka na większe zainteresowanie, w której można zdobyć szlify magistra, tudzież doktora a może nawet profesora. Wielką przydatność widzę dla niej w przemyśle i w nie dofinansowanej nauce, ponieważ wielu zakładów i instytutów nie stać na zakup drogiego sprzętu o dużej mocy obliczeniowej.
Przejdźmy już do sedna artykułu. Na pewno wielu z was posiada w domu lub w pracy stare płyty główne po modernizacji komputerów, które staracie się utrzymywać w przyzwoitej zgodności z najnowszymi osiągnięciami branży IT. Ja znalazłem 4 Pentium (2x166 i 2x200 MHz) i 1 na EX z procesorem Celeron 300A. Powkładałem to w skrzynki, dodałem RAM kupiony na giełdzie i dokupiłem tanie Realteki 10/100, oczywiście pożyczyłem też switcha. Wiadomo, że najmocniejszy komputer postawiłem jako serwer, dałem mu najwięcej pamięci i największy dysk (128MB RAMu i 10GB hdd, 2 karty sieciowe), pozostałe komputery z Pentium postawiłem jako zwykłe węzły (małe dyski 250 MB, 200MHz dostały 64 MB RAMu a te słabsze po 96MB). Gdybym jednak posiadał 5 w miarę szybkich dysków i komputery Pentium 4x200MHz plus 1x166Mhz, to ten najsłabszy postawiłbym jako serwer, ponieważ nie udostępniałby aplikacji tylko wspólny katalog do wymiany danych.
Konfiguracja polega na modyfikacji plików konfiguracyjnych. Po więcej szczegółów zalecam przeczytanie dokumentacji technicznej.
Instalujemy na serwerze nasz system (tutaj FreeBSD) i kompilujemy jądro dla potrzeb naszego sprzętu. Nie ma jakiś specjalnych wymagań dla jądra aby pracowało z LAM/MPI. Instalujemy z portów /net/lam lub z paczek najnowszą wersję (obecnie 6.5.6). Dodajemy użytkowników na których będziemy pracowali w środowisku równoległym i przygotowujemy na naszym serwerze wersje jądra dla naszych węzłów. Po co używać standardowego jądra GENERIC kiedy możemy zaoszczędzić mocy i pamięci operacyjnej. Możemy przecież wyłączać większość sprzętu w stylu SCSI, RAID, SERIALL i PARALELL PORTS i pozostawić obsługę tylko najważniejszych. Dodajemy użytkownika, najlepiej bez hasła, chociaż używałem także kont z hasłami. I te czynności powtarzamy na każdym węźle. Większość programów w stylu naszego LAM używa do autoryzacji rsh, dlatego będziemy dodawali kolejne wpisy w naszym /etc/hosts.equiv lub w katalogu domowym dodamy plik .rhosts, którego zawartość koresponduje z plikiem /etc/hosts. Istnieje jednak możliwość posłużyć się do autoryzacji ssh (znowu dokumentacja!). Odblokujmy teraz w inetd.conf poniższą linię:
I ponownie uruchamiamy inetd (jako root na każdym nodzie):
Oto przykładowy plik /etc/hosts:
10.0.0.2 node1
10.0.0.3 node2
10.0.0.4 node3
10.0.0.5 node4
Oto przykładowy plik ~/.rhosts:
node1 userlam
node2 userlam
node3 userlam
node4 userlam
Oto plik z listingiem dla LAM, który może znajdować się gdziekolwiek, np. /etc/lamhosts:
node1
node2
node3
node4
Wszystkie wymienione pliki konfiguracyjne muszą znajdować się na każdym węźle w tych samych katalogach. Warto też wspomnieć a tym aby wszystkie wpisy w tych plikach były w takiej samej kolejności, ponieważ niektóre wersje rsh "nie znoszą bałaganu". Teraz startujemy cały klaster. Narzędzie recon weryfikuje czy wszystkie węzły wystartowały:
recon: -- testing n0 (node0)
recon: -- testing n1 (node1)
recon: -- testing n2 (node2)
recon: -- testing n3 (node3)
recon: -- testing n4 (node4)
Teraz właściwy start LAMa:
Executing hboot on n0 (node0 - 1 CPU)...
Executing hboot on n1 (node1 - 1 CPU)...
Executing hboot on n2 (node2 - 1 CPU)...
Executing hboot on n3 (node3 - 1 CPU)...
Executing hboot on n4 (node4 - 1 CPU)...
lamboot powraca do naszego shella i już mamy wystartowany superkomputer. Teraz przydałoby się uruchomić równolegle jakiś program. Ponieważ nie jesteśmy jeszcze ekspertami w programowaniu równoległym posłużymy się komendą lamexec do uruchamiania "zwykłych" aplikacji. Do kompilacji w środowisku równoległym służą komendy: mpicc i mpif77, odpowiednio dla C i C++ oraz dla Fortrana, a do uruchomiania aplikacji: mpirun. Zobaczmy co oferuje lamexec:
- Składnia:
- lamexec [opcje]
- Startuje zadania na węzłach LAM nie przystosowanych do technologii MPI.
- Uwagi:
- [opcje]
- Zero lub więcej opcji wylistowanych poniżej.
- LAM/MPI schemat uruchamiania aplikacji.
- Lista węzłów lub/i procesorów LAM (przykłady poniżej).
- Program do uruchomienia.
- Opcjonalna lista argumentów w linii komend dla.
- Opcje:
- -c
- Uruchom kopii (to samo co -np).
- -D
- Zmień aktualny katalog roboczy nowych procesów na katalog gdzie rezyduje uruchomiony .
- -f
- Nie otwieraj deskryptora stdio.
- -h
- Wyświetl ten help.
- -pty
- Używaj pseudoterminala pty jeżeli standardowy to tty
- -npty
- Nie używaj pty jako standard
- -s
- Ładuj z węzła .
- -v
- Bądź gadatliwy :).
- -w/-nw
- Czekaj/Nie czekaj gdy zadanie skończone.
- -x
- Eksportuj zmienne środowiskowe z
- Węzły:
- n, np. n0-3,5
- Procesory:
- c, np. c0-3,5
- Dodatki:
- h (węzeł lokalny), o (węzeł oryginalny/pierwotny), N (wszystkie węzły), C (wszystkie procesory)
- Przykłady:
-
lamexec n0-7 prog1
wykonuje program "prog1" na węzłach od 0 do 7. -
lamexec -x FOO=bar,DISPLAY N prog2
Wykonaj "prog2" na wszystkich węzłach. W środowisku każdego procesu ustaw dla FOO wartość "bar" i ustaw DISPLAY z wartością aktualną. -
lamexec n0 N porg3
Uruchom "prog3" na węźle n0 i jeszcze raz na wszystkich. To oznacza, że na n0 uruchomiono 2 kopie "prog3". -
lamexec C prog4 arg1 arg2
Uruchom "prog4" na każdym dostępnym procesorze z argumentami "arg1" i "arg2". Jeżeli każdy węzeł posiada 1 CPU wtedy "C" jest równoważne z "N". Jeśli co najmniej jeden węzeł posiada więcej CPU wtedy LAM uruchomi wielokrotność kopii programu na tym węźle. -
lamexec c0 C prog5
Podobnie do przykładu z programem "prog3", tylko że odnosi się to do procesorów. - Domyślnie
- lamexec -w -pty
Pozostańmy przy HPC (High Permormance Computing) i wykorzystajmy nasz mały klaster dla projektu SETI@home. Pomimo, że klient setiathome nie jest stworzony do pracy w klastrach to pracując w takim środowisku będzie wykonywał się o kilkanascie procent szybciej na każdym nodzie. Muszą być tylko spełnione pewne warunki: na każdym komputerze musi pracować osobny klient (a więc także dane muszą być przeliczane tylko przez jednego klienta seti), nie można udostępniać wspólnie tego samego katalogu na różne węzły, na każdym węźle katalog dla klienta seti musi istnieć w tym samym miejscu (np. /usr/home/userlam/seti), program uruchamiany poprzez lamexec może wysyłać komunikaty na terminal (lub pseudo-terminal) ale nie mogą to być komunikaty interaktywne (np. klient prosi o zalogowanie i wpisanie adresu e-mail jako hasła). Najlepiej ściągnąć paczkę setiathome-3.03.tgz z internetu i nie instalując jej, rozpakować. Następnie przekopiować program setiathome na każdy węzeł do takiego samego katalogu. Będą zalogowanym na węźle uruchomić klienta SETI aby zalogować się na serwer i pobrać dane do przeliczenia. Następnie przerywamy obliczenia i powtarzamy te czynności na każdym węźle. Mając już przygotowane katalogi, dane i programy do uruchomienia, wpisujemy z klawiatury:
SETI@home client.
Platform: i386-unknown-freebsd2.2.8
Version: 3.03
SETI@home is sponsored by individual donors around the world.
If you'd like to contribute to the project,
please visit the SETI@home web site at
http://setiathome.ssl.berkeley.edu.
...
...
...
Scanning data file
Data Info:
Sky coordinates: 22.346 R.A., 20.180 Dec
Recorded on: 2451495.44808 (Fri Nov 12 22:45:13 1999)
Source: Arecibo Radio Observatory
Base Frequency: 1.418789060 GHz
Starting work unit without key.
Found data file: yes. Found result header file: no.
Beginning analysis...
Doing baseline smoothing.
Starting work for Doppler shift rate 0.000000, FFT length 131072
0.000133% done
Starting work for Doppler shift rate 0.000000, FFT length 65536
Starting work for Doppler shift rate 0.000000, FFT length 32768
Starting work for Doppler shift rate 0.000000, FFT length 16384
... Searching for Gaussians
Starting work for Doppler shift rate 0.000000, FFT length 8192
.............
I to wszystko o kilkanaście procent szybciej, w ten sposób liczymy kilka "workunits" na raz, to tak jakbyśmy mieli superkomputer :). Gdyby było więcej węzłów, na każdym z nich obliczenia posuwały by się szybciej, lecz w tym przypadku nie jest to zależność liniowa.
Wiem, że nie wyczerpałem tematu do końca i na przykład można coś dodać o programowaniu równoległym jak i o komendzie mpirun. Wszystko w swoim czasie. Jeśli znajdziecie jakieś błędy (także rzeczowe) proszę o e-maila.
quex, pon., 25/02/2008 - 01:40
