Message Passing Interface (MPI, message passing interface) är ett programmeringsgränssnitt ( API ) för informationsöverföring , som låter dig utbyta meddelanden mellan processer som utför samma uppgift. Designad av William Groupe , Evin Lusk och andra.
MPI är den vanligaste gränssnittsstandarden för datautbyte vid parallell programmering , och det finns implementeringar för ett stort antal datorplattformar. Används vid utveckling av program för kluster och superdatorer . Det huvudsakliga kommunikationsmedlet mellan processer i MPI är att skicka meddelanden till varandra.
MPI är standardiserat av MPI Forum . MPI-standarden beskriver ett gränssnitt för meddelandeöverföring som måste stödjas både på plattformen och i användarapplikationer . Det finns för närvarande ett stort antal gratis och kommersiella implementeringar av MPI. Det finns implementeringar för Fortran 77/90, Java , C och C++ .
MPI är i första hand inriktat på distribuerade minnessystem , det vill säga när dataöverföringskostnaderna är höga, medan OpenMP är inriktat på delade minnessystem (multi-core med delad cache). Båda teknologierna kan användas tillsammans för att optimalt utnyttja flerkärniga system i ett kluster.
Den första versionen av MPI utvecklades 1993-1994 och MPI 1 kom ut 1994.
De flesta moderna MPI-implementationer stöder version 1.1. MPI version 2.0-standarden stöds av de flesta moderna implementeringar, men vissa funktioner kanske inte är helt implementerade.
MPI 1.1 (publicerad 12 juni 1995 , implementerade första gången 2002) stöder följande funktioner:
I MPI 2.0 (publicerad 18 juli 1997 ) stöds dessutom följande funktioner:
MPI 2.1 släpptes i början av september 2008.
MPI 2.2 släpptes den 4 september 2009.
MPI 3.0 släpptes den 21 september 2012.
Den grundläggande mekanismen för kommunikation mellan MPI-processer är överföring och mottagning av meddelanden. Meddelandet innehåller de överförda data och information som gör det möjligt för den mottagande sidan att selektivt ta emot dem:
Skicka och ta emot operationer kan vara blockerande eller icke-blockerande. För icke-blockerande operationer definieras funktionerna för att kontrollera beredskapen och vänta på att operationen utförs.
En annan kommunikationsmetod är fjärrminnesåtkomst (RMA), som låter dig läsa och ändra minnesområdet för en fjärrprocess. Den lokala processen kan överföra minnesområdet för fjärrprocessen (inuti fönstret som specificeras av processerna) till dess minne och tillbaka, samt kombinera data som överförs till fjärrprocessen med data som finns tillgängliga i dess minne (till exempel , genom att summera). Alla funktioner för fjärrminnesåtkomst är icke-blockerande, men blockerande synkroniseringsfunktioner måste anropas före och efter att de utförs.
Följande är ett exempel på ett C- nummerberäkningsprogram som använder MPI :
// Inkludera obligatoriska rubriker #include <stdio.h> #inkludera <math.h> // Inklusive MPI-huvudfilen #include "mpi.h" // Funktion för mellanberäkningar dubbel f ( dubbel a ) { return ( 4,0 / ( 1,0 + a * a )); } // Huvudprogram funktion int main ( int argc , char ** argv ) { // Deklaration av variabler int done = 0 , n , myid , numprocs , i ; dubbel PI25DT = 3,141592653589793238462643 ; dubbel mypi , pi , h , summa , x ; dubbel startwtime = 0,0 , endwtime ; int namelen ; char processor_name [ MPI_MAX_PROCESSOR_NAME ]; // Initiera MPI-undersystemet MPI_Init ( & argc , & argv ); // Hämta storleken på kommunikatören MPI_COMM_WORLD // (totalt antal processer inom uppgiften) MPI_Comm_size ( MPI_COMM_WORLD , & numprocs ); // Få numret på den aktuella processen inom // kommunikatören MPI_COMM_WORLD MPI_Comm_rank ( MPI_COMM_WORLD , & myid ); MPI_Get_processor_name ( processor_name , & namelen ); // Skriv ut trådnumret i den delade poolen fprintf ( stdout , "Process %d av %d är på %s \n " , myid , numprocs , processor_name ); fflush ( stdout ); medan ( ! gjort ) { // antal intervall if ( myid == 0 ) { fprintf ( stdout , "Ange antalet intervaller: (0 avslutar) " ); fflush ( stdout ); if ( scanf ( "%d" , & n ) != 1 ) { fprintf ( stdout , "Inget nummer angett; avslutar \n " ); n = 0 _ } startwtime = MPI_Wtime (); } // Sänd antalet intervaller till alla processer (inklusive oss själva) MPI_Bcast ( & n , 1 , MPI_INT , 0 , MPI_COMM_WORLD ); om ( n == 0 ) klar = 1 ; annan { h = 1,0 / ( dubbel ) n ; summa = 0,0 ; // Beräkna punkten som tilldelas processen för ( i = myid + 1 ; ( i <= n ) ; i += numprocs ) { x = h * (( dubbel ) i - 0,5 ); summa += f ( x ); } mypi = h * summa ; // Återställ resultat från alla processer och lägg till MPI_Reduce ( & mypi , & pi , 1 , MPI_DOUBLE , MPI_SUM , 0 , MPI_COMM_WORLD ); // Om detta är huvudprocessen, skriv ut resultatet if ( myid == 0 ) { printf ( "PI är ungefär %.16lf, felet är %.16lf \n " , pi , fabs ( pi - PI25DT )); endwtime = MPI_Wtime (); printf ( "väggklocka =%lf \n " , endwtime - startwtime ); fflush ( stdout ); } } } // Släpp MPI-undersystemet MPI_Finalize (); returnera 0 ; }distribuerad och parallell beräkning | Programvara för|
---|---|
Standarder, bibliotek | |
Övervakningsprogram | |
Styrmjukvara |