Rozszerzenia MPI-2 1



Podobne dokumenty
Programowanie w modelu przesyłania komunikatów specyfikacja MPI, cd. Krzysztof Banaś Obliczenia równoległe 1

Programowanie w modelu przesyłania komunikatów specyfikacja MPI. Krzysztof Banaś Obliczenia równoległe 1

Programowanie w modelu przesyłania komunikatów specyfikacja MPI, cd. Krzysztof Banaś Obliczenia równoległe 1

Programowanie Równoległe Wykład 4. MPI - Message Passing Interface. Maciej Matyka Instytut Fizyki Teoretycznej

Programowanie w modelu przesyłania komunikatów specyfikacja MPI. Krzysztof Banaś Obliczenia równoległe 1

Programowanie Równoległe Wykład 5. MPI - Message Passing Interface. Maciej Matyka Instytut Fizyki Teoretycznej

Programowanie aplikacji równoległych i rozproszonych. Wykład 8

Programowanie współbieżne... (4) Andrzej Baran 2010/11

Tryby komunikacji między procesami w standardzie Message Passing Interface. Piotr Stasiak Krzysztof Materla

Operacje grupowego przesyłania komunikatów. Krzysztof Banaś Obliczenia równoległe 1

Operacje grupowego przesyłania komunikatów

Programowanie w standardzie MPI

Łagodne wprowadzenie do Message Passing Interface (MPI)

Message Passing Interface

Wstęp do MPI-2. Jacek Dziedzic FTiMS, Politechnika Gdańska Gdańsk, Algorytmy rozproszone 2017/2018. v1.14

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Programowanie współbieżne i rozproszone

RPC. Zdalne wywoływanie procedur (ang. Remote Procedure Calls )

Zdalne wywołanie procedur. Krzysztof Banaś Systemy rozproszone 1

Klient-Serwer Komunikacja przy pomocy gniazd

MPI dla zaawansowanych

SEGMENT TCP CZ. II. Suma kontrolna (ang. Checksum) liczona dla danych jak i nagłówka, weryfikowana po stronie odbiorczej


Modele programowania równoległego. Programowanie z przekazywaniem komunikatów Message-Passing Programming Rafał Walkowiak dla PR PP

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Programowanie Równoległe Wykład 5. MPI - Message Passing Interface (część 3) Maciej Matyka Instytut Fizyki Teoretycznej

Tworzenie aplikacji rozproszonej w Sun RPC

Wywoływanie procedur zdalnych

Część 4 życie programu

5. Model komunikujących się procesów, komunikaty

Biblioteka standardowa - operacje wejścia/wyjścia

Kolejne funkcje MPI 1

Aplikacja Sieciowa wątki po stronie klienta

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

Modele programowania równoległego. Programowanie z przekazywaniem komunikatów Message-Passing Programming Rafał Walkowiak

Pliki. Informacje ogólne. Obsługa plików w języku C

Argumenty wywołania programu, operacje na plikach

Zdalne wywoływanie procedur RPC. Dariusz Wawrzyniak 1

Opis komunikacji na potrzeby integracji z systemem klienta (12 kwiecień, 2007)

Wstęp do MPI-2. Jacek Dziedzic FTiMS, Politechnika Gdańska Gdańsk, Algorytmy rozproszone 2014/2015. v1.13

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Wywoływanie procedur zdalnych

Zdalne wywoływanie procedur RPC

Zdalne wywoływanie procedur RPC

Programowanie współbieżne Wykład 12 MPI c.d. Rafał Skinderowicz

Wywoływanie procedur zdalnych

Instytut Teleinformatyki

Lekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists()

Wprowadzenie do MPI. Interdyscyplinarne Centrum Modelowania Matematycznego i Komputerowego Uniwersytet Warszawski

Aplikacja Sieciowa. Najpierw tworzymy nowy projekt, tym razem pracować będziemy w konsoli, a zatem: File->New- >Project

76.Struktura oprogramowania rozproszonego.

Zdalne wywoływanie procedur RPC 27. października Dariusz Wawrzyniak (IIPP) 1

Zdalne wywoływanie procedur RPC 27. października 2010

Programowanie w językach

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

61 Topologie wirtualne

Struktury. Przykład W8_1

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Kolejki FIFO (łącza nazwane)

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Komunikacja za pomocą potoków. Tomasz Borzyszkowski

IPC: Kolejki komunikatów

NFS jest protokołem zdalnego wywoływania procedur (RPC)

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Pliki. Informacje ogólne. Obsługa plików w języku C

Plan wykładu. Programowanie aplikacji równoległych i rozproszonych. Wykład 8 p. Komunikacja typu punkt-punkt. Koncepcja standardu MPI

Mechanizmy pracy równoległej. Jarosław Kuchta

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Architektury systemów równoległych

SERWER AKTUALIZACJI UpServ

TCP - receive buffer (queue), send buffer (queue)

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Operacje kolektywne MPI

SERWER AKTUALIZACJI UpServ

Przykład MPI: zbiór Mandelbrota

Wstęp do Programowania, laboratorium 02

Proxy (pełnomocnik) Cel: Zastosowanie: Dostarczyć zamiennik pewnego obiektu, pozwalający kontrolować dostęp do niego.

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.

Szablony klas, zastosowanie szablonów w programach

Programowanie w Sieci Internet Blok 2 - PHP. Kraków, 09 listopada 2012 mgr Piotr Rytko Wydział Matematyki i Informatyki

Architektura typu klient serwer: uproszczony klient POP3

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Komunikacja między sterownikami przez protokół ADS

Programowanie współbieżne... (5)

Metody zawarte w klasie File: boolean createnewfile() tworzy nowy, pusty plik, ale tylko jeśli on wcześniej nie istniał. boolean delete() usuwa dany

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

PHP może zostać rozszerzony o mechanizmy dostępu do różnych baz danych:

Sieci komputerowe. Wykład 5: Warstwa transportowa: TCP i UDP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

Podstawy programowania skrót z wykładów:

SYSTEMY CZASU RZECZYWISTEGO - VxWorks

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

I - Microsoft Visual Studio C++

Zadanie 2: transakcyjny protokół SKJ (2015)

Poniższe funkcje opisane są w 2 i 3 części pomocy systemowej.

Transkrypt:

Rozszerzenia MPI-2 1

2 Dynamiczne tworzenie procesów Aplikacja MPI 1 jest statyczna z natury Liczba procesów określana jest przy starcie aplikacji i się nie zmienia. Gwarantuje to szybką komunikację procesów. Ładnie współpracuję z menadżerami zasobów (np. PBS/TORQUE). Kiedy MPI_Init powraca, wszystkie procesy wystartowały i są elementami komunikatora MPI_COMM_WORLD. Każdy proces może się komunikować z każdym innym procesem aplikacji używając MPI_COMM_WORLD. MPI-2 dostarcza mechanizmy do Kolektywnego tworzenia nowych procesów. Połączenia dwóch aplikacji stworzonych niezależnie Dynamicznego tworzenie i łączenie procesów wykorzystuje intensywnie pojęcie interkomunikatora zdefiniowane już w MPI-1, ale rzadko wykorzystywane.

Interkomunikator Interkomunikator w MPI Grupa A 2 1 3 Grupa B 2 1 3 Z punktu widzenie procesu wysyłającego grupa lokalna to A, zdalna B, a procesu odbierającego grupa lokalna to B, zdalna A 0 Interkomunikator składa się z dwóch grup procesów. Grupa której proces jest członkiem, to grupa lokalna (dla tego procesu) a której proces nie jest członkiem to grupa zdalna. Wszystkie operacje Send/Recv odbywają się pomiędzy procesami różnych grup. Numer procesu nadawcy (operacja Send) oraz odbiorcy (operacja Recv) jest numerem w grupie zdalnej. MPI_Comm_size na interkomunikatorze zwraca rozmiar grupy lokalnej, MPI_Comm_remote_size grupy zdalnej. Operacje grupowe w MPI-1 niezdefiniowane, w MPI-2 dostępne (np. MPI_Bcast jeden proces z grupy lokalnej wysyła informacje wszystkim procesom grupy zdalnej) 3

Operacja MPI_Comm_spawn MPI_Comm_spawn(char *command,char *argv[], int maxprocs,mpi_info info,int root, MPI_Comm comm, MPI_Comm *intercomm, int errorcodes[]) Tworzy maxprocs potomnych procesów MPI, przy czym każdy z nich powstaje w wyniku uruchomienie programu command. argv zawiera argumenty programu (wiersz polecenia), przy czym w odróżnieniu od konwencji języka C, argv[0] nie jest nazwą programu Jest to operacja kolektywna, która jest wykonywana przez wszystkie procesy rodzicielskie w komunikatorze comm (np. MPI_COMM_WORLD). Tylko proces o numerze root musi dostarczyć argumenty na lewo od root. Wynikiem jest interkomunikator z punktu widzenia procesów rodzicielskich grupa lokalna składa się z procesów rodzicielskich a zdalna z potomnych. Interkomunikator ten może być pobrany przez procesy potomne funkcją int MPI_Comm_get_parent(MPI_Comm *parent). Oczywiście z punktu widzenia procesów potomnych grupa zdalna składa się z procesów rodzicielskich a lokalna z potomnych. Procesy potomne mają swój własny komunikator MPI_COMM_WORLD. 4

Obiekty typu MPI_Info 5 Służą do przekazywania funkcjom MPI-2 dodatkowych, niestandardowych informacji, wpływających na działanie funkcji i przekazujących informacje zależne od implementacji MPI oraz środowiska (menadżer zasobów, system operacyjny). Obiekt jest tworzony funkcją int MPI_Info_create(MPI_Info *info) a zwalniany funkcją int MPI_Info_free(MPI_Info *info). Obiekt jest kolekcją par (klucz,wartość) Funkcja MPI_Info_set(MPI_Info info, char *key,char *value) dodaje do obiektu info parę (key,value). Wartość domyślna MPI_INFO_NULL. Klucze w implementacji OpenMPI host - wartość jest nazwą maszyny, na której uruchomić procesy. hosts - nazwa pliku z nazwami maszyn. path - ścieżka do pliku wykonywalnego. wdir - katalog roboczy do pliku wykonywalnego.

Łączenie niezależnie uruchomionych aplikacji MPI - strona serwera Mechanizm w MPI oparty jest na modelu klient-serwer i przypomina interfejs gniazd protokołu TCP. Funkcja int MPI_Open_port(MPI_Info info, char *port_name) tworzy nazwę portu na którym serwer będzie odbierał połączenia. Funkcja int MPI_Close_port(char *port_name) zamyka otwarty port. Nazwę portu należy ręcznie przekazać klientom. Funkcja int MPI_Comm_accept(char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm) tworzy połączenie aplikacji serwera z aplikacją klienta. Jest wywoływana kolektywnie przez wszystkie procesy w komunikatorze comm (np. MPI_COMM_WORLD). Tworzy interkomunikator do komunikacji z klientem i zapisuje go pod adresem newcomm Argumenty info i port_name są dostarczane tylko przez proces o numerze root. Rozłączenie serwera i klienta przy pomocy funkcji int MPI_Comm_disconnect (MPI_Comm *comm). wywołanej na interkomunikatorze otrzymanym w wyniku MPI_Comm_accept. 6

Łączenie niezależnie uruchomionych aplikacji MPI - strona klienta 7 Funkcja int MPI_Comm_connect(char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm) jest wykonywana kolektywnie przez procesy klienta na komunikatorze comm. Wykonuje połączenie z serwerem nasłuchującym na porcie port_name, tworzy interkomunikator do komunikacji z serwerem i zapisuje go pod adresem newcomm. Nazwę portu należy jakoś przekazać klientowi od serwera. Klient rozłącza się również przy pomocy funkcji. W następującym przykładzie Serwer składa się z jednego procesu. Przetwarza dane przesłane przez klienta do momentu gdy odbierze komunikat o etykiecie 1. Komunikat o etykiecie zero kończy pracę serwera. Klient pobiera nazwę portu z wiersza poleceń.

8 Przykład: serwer (1) #include "mpi.h" int main( int argc, char **argv ) { MPI_Comm client; MPI_Status status; // MAX_PORT_NAME to maksymalna długość nazwy portu char pname[mpi_max_port_name]; double buf[max_data]; int size, again; MPI_Init( &argc, &argv ); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size!= 1) MPI_Abort(MPI_COMM_WORLD,1); MPI_Open_port(MPI_INFO_NULL, pname); printf("server available at %s\n",pname); while (1) { // Nawiąż połączenie z klientem MPI_Comm_accept(pname,MPI_INFO_NULL,0,MPI_COMM_WORLD, &client ); again = 1;

Przykład: serwer (2) 9 } while (again) { // Odbierz komunikat od dowolnego procesu klienta MPI_Recv( buf, MAX_DATA, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, client,&status ); switch (status.mpi_tag) { // Zakończ pracę serwera case 0: MPI_Comm_free( &client ); MPI_Close_port(port_name); MPI_Finalize(); return 0; // Rozłącz się z klientem // i akceptuj połączenia na nowo case 1: MPI_Comm_disconnect( &client ); again = 0; break; case 2: // zrób coś z komunikatem } } }

Przykład: klient #include "mpi.h" int main( int argc, char **argv ) { MPI_Comm server; double buf[max_data]; char port_name[mpi_max_port_name]; MPI_Init( &argc, &argv ); // Nazwa portu przekazana przez wiersz polecenia strcpy(port_name, argv[1] ); // Połącz się z serwerm tworząc interkomunikator MPI_Comm_connect( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD,&server ); } while (!done) { tag = 2; MPI_Send( buf, n, MPI_DOUBLE, 0, tag, server ); done =... } MPI_Send( buf, 0, MPI_DOUBLE, 0, 1, server ); MPI_Comm_disconnect( &server ); MPI_Finalize(); 10

11 Publikowanie nazw Poprzedni przykład był dość niewygodny, ponieważ nazwę portu wydrukowaną przez serwer trzeba było ręcznie wpisać do wiersza poleceń, aby przekazać ją klientowi. Interfejs publikowania nazw pozwala na publikację nazwy portu przez serwer pod nazwą usługi przy pomocy funkcji int MPI_Publish_name(char *service_name, MPI_Info info, char *port_name). Publikacja obowiązuje aż do wywołania int MPI_Unpublish_name(char *service_name, MPI_Info info, char *port_name). Nazwa portu może być uzyskana przez klienta przy pomocy funkcji: int MPI_Lookup_name(char *service_name, MPI_Info info, char *port_name). Problem polega na zapewnieniu widoczności publikowanych nazw poza obręb aplikacji serwera.

12 Ublikowanie nazw - przykład Strona serwera MPI_Open_port(MPI_INFO_NULL, port_name); MPI_Publish_name("ocean", MPI_INFO_NULL, port_name); MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm); /* Zrób coś z interkomunikatorem intercomm */ MPI_Unpublish_name("ocean", MPI_INFO_NULL, port_name); Strona klienta MPI_Lookup_name("ocean", MPI_INFO_NULL, port_name); MPI_Comm_connect( port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm);

13 Plikowe wejście/wyjście Stanowiło problem w Państwa projekcie. (w programie Mandelbrot). Rozwiązanie w postaci jednego centralnego procesu odbierającego dane od pozostałych i zapisującego je do pliku bardzo źle się skaluje. Inne rozwiązania np. każdy proces zapisuje dane do swojego pliku też nie wyglądają zachęcająco. Potrzebne jest rozwiązanie pozwalające na równległy zapis przez wiele procesów do wspólnego pliku. Rozwiązanie powinno wspierać istniejące równoległe systemy plików (n.p. PIOFS oraz GPFS IBMa, GFS firmy RedHat,...) Uwaga: Funkcje wejścia wyjścia w MPI są dla nieformatowanych plików binarnych.

Otwarcie pliku int MPI_File_open(MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh) Otwarcie to operacja kolektywna dla wszystkich procesów w komunikatorze comm. filename to ścieżka do pliku, a info to wskazówki dla implementacji. amode to tryb otwarcia; jedna ze stałych lub suma bitowa: MPI_MODE_RDONLY tylko do odczytu MPI_MODE_RDWR odczyt i zapis MPI_MODE_WRONLY tylko zapis MPI_MODE_CREATE stwórz plik jeśli nie istnieje MPI_MODE_EXCL błąd jeżeli próbujesz stworzyć plik który istnieje MPI_MODE_DELETE_ON_CLOSE usuwa plik po zamknięciu MPI_MODE_UNIQUE_OPEN nikt inny nie otworzy pliku, MPI_MODE_SEQUENTIAL dostęp wyłącznie sekwencyjny MPI_MODE_APPEND wszystkie wskaźniki do pliku ustaw na koniec. Pod adresem fh zostanie zapisany uchwyt do pliku, który jest podawany we wszystkich operacjach na nim. 14

15 Zamknięcie pliku i kilka innych operacji. Funkcja int MPI_File_close(MPI_File *fh) zamyka plik. Zamknięcie jest również operacją kolektywną. (muszą wywołać je wszystkie procesy w komunikatorze) Nie podajemy komunikatora, bo komunikator jest przechowywany w obiekcie MPI_File. Wszystkie pliki muszą być zamknięte przed wykonaniem. Funkcja int MPI_File_delete(char *filename, MPI_Info info), będąca operacją kolektywną usuwa plik o nazwie filename. Funkcja int MPI_File_get_size(MPI_File fh, MPI_Offset *size) zapisuje pod adresem size rozmiar pliku. Funkcja int MPI_File_preallocate(MPI_File fh, MPI_Offset size) będąca operacją kolektywną zwiększa rozmiar pliku do size jednocześnie alokując przestrzeń w pamięci masowej dla zwiększonego pliku.

Odczyt/zapis indywidualny int MPI_File_read(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) wykonuje odczyt count elementów typu datatype do bufora o adresie buf zapisując status tej operacji pod adresem status. int MPI_File_write(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) wykonuje zapis do pliku. Funkcje te nie są operacjami kolektywnymi!!! Odczyt/zapis jest wykonany przez każdy proces indywidualnie. Semantyka podobna jak w przypadku wywołań systemowych Linuksa. W MPI każdy proces ma własny wskaźnik bieżącej pozycji w pliku. Może on być zmieniany na wartość offset przy pomocy funkcji int MPI_File_seek(MPI_File fh, MPI_Offset offset, int whence), gdzie parametr whence może przyjąć jedną z trzech wartości: MPI_SEEK_SET ustaw wskaźnik od początku pliku MPI_SEEK_CUR ustaw wskaźnik od bieżącej pozycji wskaźnika MPI_SEEK_END ustaw wskaźnik od końca pliku 16

Przykład 17... P 0 P 1 P 2 P N-1 Mamy N procesów, każdy chce odczytać blok bajtów (o identycznej długości). Bloki bajtów poszczególnych procesów są umieszczone jeden po drugim. Jeżeli długość bloku jest równa M, to proces o numerze i odczytuje bajty od numeru i*m do i*m+m-1. Czy ten przykład coś Państwu przypomina???.

#include "mpi.h" #define FILESIZE (1024 * 1024) Kod programu int main(int argc, char **argv) { int *buf, rank, nprocs, nints, bufsize; MPI_File fh; MPI_Status status; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); } bufsize = FILESIZE/nprocs; //rozmiar bloku pliku buf = (int *) malloc(bufsize); nints = bufsize/sizeof(int); //liczba elementów typu MPI_INT MPI_File_open(MPI_COMM_WORLD, "datafile",mpi_mode_rdonly, MPI_INFO_NULL, &fh); MPI_File_seek(fh, rank*bufsize, MPI_SEEK_SET); MPI_File_read(fh, buf, nints, MPI_INT, &status); MPI_File_close(&fh); free(buf); MPI_Finalize(); return 0; 18

Co robić w sytuacji gdy każdy proces chce otworzyć inny plik? 19 Otwieranie kolektywne n plików przez n procesów na komunikatorze MPI_COMM_WORLD nie ma sensu Użyć ulubionego interfejsu we/wy (fopen, etc.) Użyć predefiniowanego komunikatora MPI_COMM_SELF jest to komunikator którego członkiem jest jedynie aktualny proces.

Nieblokujące operacje plikowego we/wy Funkcje int MPI_File_iread(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Request *request) oraz int MPI_File_iwrite(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Request *request) wykonują nieblokujący odczyt/zapis do pliku Funkcje inicjalizują odczyt/zapis, po czym pod adresem request tworzą obiekt żądania identyfikujący trwającą operację odczytu/zapisu. Na obiekcie żądania może być wykonana funkcja MPI_Wait wstrzymująca wołający proces do momentu zakończenia operacji (Uwaga: zakończenie operacji nie oznacza że dane są na dysku! - służy do tego funkcja MPI_File_sync lub MPI_Test sprawdzająca czy operacja się zakończyła bez blokowania procesu. Pozwalają na nakładanie się obliczeń i operacji plikowego we/wy: MPI_Request request; MPI_Status &status; MPI_File_iwrite(fh,buf,count,MPI_DOUBLE,&request) /* Teraz wykonaj obliczenia!!! */ MPI_Wait(&request,&status); 20

21 Odczyt i zapis od określonej pozycji z pliku int MPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, MPI_Status *status). int MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, MPI_Status *status). Dodatkowy parametr offset specyfikuje pozycje w pliku, od której ma nastąpić odczyt. Należy stosować te funkcje zamiast pary MPI_File_seek+funkcja odczytująca/zapisująca w aplikacjach wielowątkowych (kto wie dlaczego???). Istnieją również wersje nieblokujące: MPI_File_iwrite_at oraz MPI_File_iread_at.

22 Operacje kolektywne Funkcje odczytu/zapisu omówione dotychczas nie są operacjami kolektywnymi. A zatem możliwa jest sytuacja w której plik otwierany jest kolektywnie przez wszystkie procesy w komunikatorze MPI_COMM_WORLD a następnie zapis/odczyt jest wykonywany przez jeden proces. Funkcje int MPI_File_read_all(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) oraz int MPI_File_write_all(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) służą do przeprowadzania kolektywnej operacji wejścia wyjście przez wszystkie procesy w komunikatorze. W przypadku operacji kolektywnej implementacja wie, że inne procesy również wykonują operację, co pozwala na przeprowadzenie szeregu optymalizacji. W naszym przykładzie zastosowanie operacji kolektywnych może prowadzić do wzrostu wydajności. Funkcje MPI_File_read_at oraz MPI_File_write_at mają również swoje kolektywne wersje.

23 Co robić w sytuacji następującego dostępu... P 0 P 1 P 2 P 0 P 1 P 2 P 0 P 1 P 2 P 0 P 1 P 2 Każdy proces ma do zapisania n bloków do pliku (Ciekawe, czy to coś Państwu przypomina?) Wyjście najprostsze n operacji dyskowych przez każdy proces. Wyjście skomplikowane: Każdy proces definiuje nieciągły widok pliku i zapis jedną operacją kolektywną może prowadzić do znacznie większej wydajności na odpowiednim sprzęcie i implementacji MPI.

24 To wszystko na dzisiaj Pominęliśmy widoki plików Oraz komunikację jednostronną (one-sided communication). Życzę powodzenia na zaliczeniu.