Ansluter MPI i Visual Studio

Det hände så att jag fick ett nära möte med studiet av parallell beräkning och i synnerhet MPI. Kanske är den här riktningen mycket lovande idag, så jag skulle vilja visa hubbrowsers grunderna i denna process.

Grundläggande principer och exempel
Beräkningen av exponentiell (e) kommer att användas som exempel. Ett av alternativen för att hitta det är Taylor-serien:
e^x=∑((x^n)/n!), där summeringen sker från n=0 till oändligt.

Denna formel kan lätt parallelliseras, eftersom det erforderliga antalet är summan av individuella termer och tack vare detta kan varje enskild processor börja beräkna de individuella termerna.

Antalet termer som kommer att beräknas i varje enskild processor beror både på längden på intervallet n och på det tillgängliga antalet processorer k som kan delta i beräkningsprocessen. Så, till exempel, om längden på intervallet är n=4, och fem processorer (k=5) är involverade i beräkningarna, kommer den första till fjärde processorn att få vardera en term, och den femte kommer inte att användas. Om n=10 och k=5 kommer varje processor att få två termer för beräkning.

Inledningsvis skickar den första processorn, med användning av MPI_Bcast broadcast-funktionen, till de andra värdet på den användarspecificerade variabeln n. I allmänhet har MPI_Bcast-funktionen följande format:
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm), där buffert är adressen till bufferten med elementet, count är antalet element, datatype är motsvarande datatyp i MPI, root är rangen för huvudprocessorn som hanterar vidarebefordran, och comm är namnet på kommunikatören.
I mitt fall kommer huvudprocessorns roll, som redan nämnts, att vara den första processorn med rang 0.

Efter att numret n har skickats framgångsrikt kommer varje processor att börja beräkna sina termer. För att göra detta, vid varje steg i cykeln, kommer ett nummer lika med antalet processorer som deltar i beräkningarna att läggas till talet i, vilket initialt är lika med processorns rangordning. Om numret pågår nästa steg antal jag kommer att överträffa användardefinierad nummer n, loop exekvering för av denna processor ska sluta.

Under utförandet av cykeln kommer villkoren att läggas till i en separat variabel och, efter att den har slutförts, kommer det resulterande beloppet att skickas till huvudprocessor. För att göra detta kommer funktionen MPI_Reduce reducering att användas. I allmän syn det ser ut så här:
int MPI_Reduce(void *buf, void *result, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

Den sammanfogar ingångsbuffertelementen för varje process i gruppen med hjälp av operationen och returnerar det kombinerade värdet till utgångsbufferten för processnummerroten. Resultatet av en sådan operation blir ett enda värde, vilket är anledningen till att casting-funktionen fick sitt namn.

Efter att ha kört programmet på alla processorer kommer den första processorn att ta emot totala summan termer, vilket kommer att vara exponentvärdet vi behöver.

Det bör noteras att både parallellt och sekventiella metoder Vid beräkning av exponenten används en rekursiv funktion för att hitta faktorialet. När jag fattade ett beslut om hur man skulle parallellisera uppgiften som utförs, övervägde jag alternativet att hitta faktorialen också på olika processorer, men i slutändan var det här alternativet irrationellt för mig.

Den primära uppgiften är fortfarande att hitta värdet på exponenten, och om processorer börjar beräkna varje faktor för varje term separat, kan detta leda till den raka motsatta effekten, nämligen en betydande förlust i prestanda och beräkningshastighet.
Detta förklaras av det faktum att det i det här fallet kommer att börja enormt tryck på kommunikationsmiljön, som redan ofta är en svag länk i parallella datorsystem. Om faktorn beräknas privat på varje processor, blir belastningen på kommunikationslinjerna minimal. Det här fallet kan kallas bra exempel att parallelliseringsuppgiften också ibland måste ha sina gränser.

Kodexekveringsalgoritm
1. Värdet på siffran n överförs från det visuella skalet till programmet, som sedan skickas till alla processorer med hjälp av broadcast-funktionen.
2. När den första huvudprocessorn initieras startar en timer.
3. Varje processor exekverar en loop, där inkrementvärdet är antalet processorer i systemet. Vid varje iteration av loopen beräknas en term och summan av sådana termer lagras i variabeln drobSum.
4. När slingan är klar lägger varje processor till sitt drobSum-värde till Result-variabeln med hjälp av MPI_Reduce-reduktionsfunktionen.
5. Efter att ha slutfört beräkningar på alla processorer, stoppar den första huvudprocessorn timern och skickar det resulterande värdet av Result-variabeln till utgångsströmmen.
6. Tidsvärdet som mäts av vår timer i millisekunder skickas också till utströmmen.
Kodlista
Programmet är skrivet i C++, vi kommer att anta att argumenten för exekvering skickas från det externa skalet. Koden ser ut så här:
#omfatta "mpi.h"
#omfatta
#omfatta
använder namnutrymme std;

dubbelfakta(int n)
{
om (n==0)
retur 1;
annan
returnera n*Faktum(n-1);
}

int main(int argc, char *argv)
{
SetConsoleOutputCP(1251);
int n;
int myid;
int numprocs;
int i;
int rc;
lång dubbeldrob,drobSum=0,Resultat, summa;
dubbel starttid = 0,0;
dubbel sluttid;

N = atoi(argv);

if (rc= MPI_Init(&argc, &argv))
{
cout<< "Startfel, exekveringen stoppades" << endl;
MPI_Abort(MPI_COMM_WORLD, rc);
}

MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);

if (myid == 0)
{

Startwtime = MPI_Wtime();
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

för (i = myid; i<= n; i += numprocs)
{
drob = 1/Fakta(i);
drobSum += drob;
}

MPI_Reduce(&drobSum, &Resultat, 1, MPI_LONG_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
cout.precision(20);
if (myid == 0)
{
cout<< Result << endl;
endwtime = MPI_Wtime();
cout<< (endwtime-startwtime)*1000 << endl;
}

MPI_Finalize();
returnera 0;
}


* Den här källkoden markerades med Source Code Highlighter.
Slutsats
Således fick vi ett enkelt program för att beräkna exponenten med hjälp av flera processorer samtidigt. Förmodligen är flaskhalsen att lagra själva resultatet, för med en ökning av antalet siffror kommer det inte att vara trivialt att lagra ett värde med standardtyper och denna plats kräver utarbetning. Kanske är en ganska rationell lösning att skriva resultatet till en fil, även om det, med tanke på det här exemplets rent pedagogiska funktion, inte behöver fokusera mycket på detta.

Parallellisering i C-språk
Exempel 3b. Parallellisering i Fortran
Exempel 4a. Fastställande av egenskaperna för systemtimern i C-språk
Exempel 4b. Definiera systemtimeregenskaper i Fortran

1.4. Skicka och ta emot meddelanden mellan separata processer

1.4.1. Punkt till punkt operationer

1.4.2. Skicka och ta emot meddelanden med blockering

Exempel 5a. Utbyte av meddelanden mellan två processer i C-språk
Exempel 5b. Utbyte av meddelanden mellan två processer i Fortran
Exempel 6a. Meddelandeutbyte mellan jämna och udda processer i C
Exempel 6b. Meddelandeutbyte mellan jämna och udda processer i Fortran
Exempel 7a. Vidarebefordran till en obefintlig process i C
Exempel 7b. Vidarebefordran till en obefintlig process i Fortran
Exempel 8a. Buffrad datasändning på C-språk
Exempel 8b. Buffrad datasändning på Fortran-språket
Exempel 9a. Få information om meddelandeattribut på C-språk
Exempel 9b. Få information om meddelandeattribut i Fortran
Exempel 10a. Definition av latens och genomströmning i C-språk
Exempel 10b. Definierar latens och genomströmning i Fortran

1.4.3. Skicka och ta emot meddelanden utan att blockera

Exempel 11a. Utbyte över en ringtopologi med hjälp av icke-blockerande operationer i C
Exempel 11b. Byt över en ringtopologi med hjälp av icke-blockerande operationer i Fortran
Exempel 12a. Kommunikationsschema "mästare - arbetare" på C-språk
Exempel 12b. Kommunikationsdiagram "mästare - arbetare" på Fortran-språket
Exempel 13a. Matristransponering i C-språk
Exempel 13b. Transponera en matris i Fortran

1.4.4. Väntande interaktionsbegäranden

Exempel 14a. Schema för en iterativ metod med utbyte längs en ringtopologi med användning av uppskjutna frågor i C-språk
Exempel 14b. Schema för en iterativ metod med utbyte över en ringtopologi med uppskjutna frågor i Fortran

1.4.5. dödlägessituationer

Exempel 15a. Utbyte över en ringtopologi med MPI_Sendrecv-proceduren i C-språk
Exempel 15b. Byt över en ringtopologi med MPI_SENDRECV-proceduren i Fortran

1.5. Kollektiva processinteraktioner

1.5.1. Allmänna bestämmelser

1.5.2. Barriär

Exempel 16a. Modellering av barriärsynkronisering i C-språk
Exempel 16b. Modellering av barriärsynkronisering i Fortran

1.5.3. Kollektiv dataöverföring

1.5.4. Global verksamhet

Exempel 17a. Modellering av global summering med hjälp av ett dubbleringsschema och den kollektiva operationen MPI_Reduce i C-språk
Exempel 17b. Modellering av global summering med hjälp av ett dubbleringsschema och den kollektiva operationen MPI_Reduce i Fortran

1.5.5. Anpassad global verksamhet

Exempel 18a. Anpassad global funktion i C-språk
Exempel 18b. Anpassad global funktion i Fortran

1.6. Grupper och kommunikatörer

1.6.1. Allmänna bestämmelser

1.6.2. Verksamhet med processgrupper

Exempel 19a. Arbeta med grupper i C
Exempel 19b. Arbeta med grupper i Fortran

1.6.3. Verksamhet med kommunikatörer

Exempel 20a. Att bryta ner en kommunikatör i C
Exempel 20b. Partitionering av en kommunikatör i Fortran
Exempel 21a. Omnumrering av processer i C-språk
Exempel 21b. Omnumrering av processer i Fortran

1.6.4. Interkommunikatörer

Exempel 22a. Master-worker-schema som använder en intercommunicator på C-språk
Exempel 22b. Master-worker-krets som använder en intercommunicator i Fortran

1.6.5. Attribut

1.7. Virtuella topologier

1.7.1. Allmänna bestämmelser

1.7.2. Kartesisk topologi

1.7.3. Graftopologi

Exempel 23a. Master-worker diagram med graftopologi i C-språk
Exempel 23b. Master-worker-schema med graftopologi i Fortran

1.8. Skicka olika typer av data

1.8.1. Allmänna bestämmelser

1.8.2. Härledda datatyper

Exempel 24a. Ordna om matriskolumner i omvänd ordning i C-språk
Exempel 24b. Omordna matriskolumner i omvänd ordning i Fortran

1.8.3. Datapaketering

Exempel 25a. Skickar packad data på C-språk
Exempel 25b. Skickar packad data i Fortran

1.9. info objekt

1.9.1. Allmänna bestämmelser

1.9.2. Arbeta med infoobjektet

1.10. Dynamisk processkontroll

1.10.1. Allmänna bestämmelser

1.10.2.Skapande av processer

master.c
slav.c
Exempel 26a. Master-worker-schema som använder process spawning i C-språk
mästare.f
slav.f
Exempel 26b. Master-worker-schema som använder process spawning i Fortran

1.10.3. Kommunikation mellan klient och server

server.c
klient.c
Exempel 27a. Datautbyte mellan server och klient via offentligt namn på C-språk
server.f
klient.f
Exempel 27b. Utbyte av data mellan server och klient med offentligt namn på Fortran-språket

1.10.4. Ta bort en processassociation

1.10.5. Socket kommunikation

1.11. Envägskommunikation

1.11.1. Allmänna bestämmelser

1.11.2. Arbeta med ett fönster

1.11.3. Dataöverföring

1.11.4. Synkronisering

Exempel 28a
Exempel 28b
Exempel 29a. Utbyte över en ringtopologi med envägskommunikation i C
Exempel 29b. Utbyte över en ringtopologi med envägskommunikation i Fortran
Exempel 30a. Utbyte över en ringtopologi med envägskommunikation i C
Exempel 30b. Utbyte över en ringtopologi med envägskommunikation i Fortran

1.12. Externa gränssnitt

1.12.1. Allmänna frågor

1.12.2. Information från status

1.12.3. Trådar

1.13. Parallell I/O

1.13.1. Definitioner

1.13.2. Arbeta med filer

1.13.3. Datatillgång

Exempel 31a. Buffrad läsning från en fil på C-språk
Exempel 31b. Buffrad läsning från en fil i Fortran
Exempel 32a. Kollektiv läsning från en fil på C-språk
Exempel 32b. Kollektiv läsning från en fil i Fortran

1.14. Fel vid bearbetning

1.14.1. Allmänna bestämmelser

1.14.2. Felhanterare associerade med kommunikatörer

1.14.3. Fönsterrelaterade felhanterare

1.14.4. Filrelaterade felhanterare

1.14.5. Ytterligare procedurer

1.14.6. Felkoder och klasser

1.14.7. Ringer felhanterare

Exempel 33a. Felhantering i C-språk
Exempel 33b. Felhantering i Fortran

Kapitel 2 OpenMP Parallell Programmeringsteknik

2.1. Introduktion

2.2. Grundläggande koncept

2.2.1. Att kompilera ett program

Exempel 34a. Villkorlig sammanställning i C
Exempel 34b
Exempel 34c. Villkorlig sammanställning i Fortran

2.2.2. Parallell programmodell

2.2.3. Direktiv och förfaranden

2.2.4. Programexekvering

2.2.5. Timing

Exempel 35a. Arbeta med systemtimer i C
Exempel 35b. Arbetar med systemtimer i Fortran

2.3. Parallella och seriella områden

2.3.1. parallelldirektiv

Exempel 36a. Parallell region i C-språk
Exempel 36b. Parallell region i Fortran
Exempel 37a. Reduktionsalternativet i C-språk
Exempel 37b. Reduktionsalternativet i Fortran

2.3.2. Stenografi

2.3.3. Miljövariabler och hjälprutiner

Exempel 38a. Omp_set_num_threads procedur och num_threads alternativ i C-språk
Exempel 38b. Procedur omp_set_num_threads och alternativet num_threads på Fortran-språket
Exempel 39a. Procedurer omp_set_dynamic och omp_get_dynamic i C-språk
Exempel 39b. Procedurer omp_set_dynamic och omp_get_dynamic i Fortran
Exempel 40a. Kapslade parallella regioner i C
Exempel 40b. Kapslade parallella regioner i Fortran
Exempel 41a. Omp_in_parallel funktion i C-språk
Exempel 41b. omp_in_parallel funktion på Fortran-språket

2.3.4. ett enda direktiv

Exempel 42a. Enkelt direktiv och numera alternativ i C-språk
Exempel 42b. Enkelt direktiv och numera alternativ i Fortran
Exempel 43a. Alternativet Copyprivate i C-språk
Exempel 43b. copyprivate alternativ i Fortran

2.3.5. huvuddirektiv

Exempel 44a. Masterdirektiv i C-språk
Exempel 44b. masterdirektiv i Fortran

2.4. Datamodell

Exempel 45a. Privat alternativ i C-språk
Exempel 45b. Det privata alternativet i Fortran
Exempel 46a. Delat alternativ i C-språk
Exempel 46b. Det delade alternativet i Fortran
Exempel 47a. firstprivate alternativet i C-språk
Exempel 47b. förstaprivata alternativet i Fortran
Exempel 48a. trådprivat direktiv på C-språk
Exempel 48b. trådprivat direktiv i Fortran
Exempel 49a. Kopieringsalternativ på C-språk
Exempel 49b. kopieringsalternativ i Fortran

2.5. Arbetsfördelning

2.5.1. Lågnivå parallellisering

Exempel 50a. Procedurer omp_get_num_threads och omp_get_thread_num på C-språk
Exempel 50b. Procedurer omp_get_num_threads och omp_get_thread_num i Fortran

2.5.2. Parallella slingor

Exempel 51a. för direktiv på C-språk
Exempel 51b. Do-direktivet i Fortran
Exempel 52a. Schemaalternativ på C-språk
Exempel 52b. schemaalternativ i Fortran
Exempel 53a. Schemaalternativ på C-språk

Anteckning: Föreläsningen ägnas åt övervägandet av MPI-teknik som en parallell programmeringsstandard för distribuerade minnessystem. Huvudsätten för dataöverföring beaktas. Begrepp som processgrupper och kommunikatörer introduceras. Täcker grundläggande datatyper, punkt-till-punkt operationer, kollektiva operationer, synkroniseringsoperationer och tidsmätningar.

Syftet med föreläsningen: Föreläsningen syftar till att studera den allmänna metodiken för att utveckla parallella algoritmer.

Videoinspelning av föreläsningen - (volym - 134 MB).

5.1. MPI: grundläggande begrepp och definitioner

Låt oss överväga ett antal begrepp och definitioner som är grundläggande för MPI-standarden.

5.1.1. Konceptet med ett parallellt program

Under parallellt program inom ramen för MPI förstår vi en uppsättning av samtidigt körda processer. Processer kan köras på olika processorer, men flera processer kan också placeras på samma processor (i det här fallet exekveras de i tidsdelningsläge). I extremfallet kan en enda processor användas för att köra ett parallellprogram - som regel används denna metod för att initialt kontrollera det parallella programmets korrekthet.

Varje process i ett parallellt program skapas från en kopia av samma programkod ( SPMP-modell). Denna programkod, presenterad i form av ett körbart program, måste vara tillgänglig vid den tidpunkt då parallellprogrammet startas på alla processorer som används. Källkoden för det körbara programmet är utvecklad i de algoritmiska språken C eller Fortran med en eller annan implementering av MPI-biblioteket.

Antalet processer och antalet processorer som används bestäms vid den tidpunkt då parallellprogrammet startas med hjälp av MPI-programexekveringsmiljön och kan inte ändras under beräkningar (MPI-2-standarden ger möjlighet att dynamiskt ändra antalet processer). Alla programprocesser är sekventiellt numrerade från 0 till p-1, Var sidär det totala antalet processer. Processnumret anropas rang bearbeta.

5.1.2. Dataöverföringsoperationer

MPI baseras på meddelandeöverföringsoperationer. Bland funktionerna som tillhandahålls som en del av MPI finns det olika dubbel (punkt till punkt) operationer mellan två processer och kollektiv (kollektiv) kommunikationsåtgärder för samtidig interaktion mellan flera processer.

För att utföra parade operationer kan olika överföringslägen användas, inklusive synkron, blockering etc. - en fullständig övervägande av ev. överföringslägen kommer att utföras i avsnitt 5.3.

Som nämnts tidigare tillhandahåller MPI-standarden behovet av att implementera de flesta av de grundläggande kollektiva dataöverföringsoperationerna - se underavsnitt 5.2 och 5.4.

5.1.3. Begreppet kommunikatörer

Parallella programprocesser kombineras till grupper. Under meddelare MPI avser ett speciellt skapat tjänsteobjekt som kombinerar en grupp av processer och ett antal ytterligare parametrar ( sammanhang) används när du utför dataöverföringsoperationer.

Vanligtvis utförs parade dataöverföringsoperationer för processer som tillhör samma kommunikatör. Kollektiva operationer tillämpas samtidigt på alla kommunikatörsprocesser. Som ett resultat av detta är det obligatoriskt att ange vilken kommunikator som ska användas för dataöverföringsoperationer i MPI.

Under beräkningar kan nya processgrupper och kommunikatörer skapas och befintliga grupper av processer och kommunikatörer kan raderas. Samma process kan tillhöra olika grupper och kommunikatörer. Alla processer som finns i det parallella programmet ingår i communicatorn som skapas som standard med identifieraren MPI_COMM_WORLD.

Om det är nödvändigt att överföra data mellan processer från olika grupper, är det nödvändigt att skapa en global kommunikatör ( intercommunicator).

En detaljerad diskussion om MPI:s förmåga att arbeta med grupper och kommunikatörer kommer att genomföras i underavsnitt 5.6.

5.1.4. Datatyper

När du utför meddelandeöverföringsoperationer måste du ange vilken data som ska skickas eller tas emot i MPI-funktioner. typ skickade data. MPI innehåller ett stort set grundläggande typer data som till stor del sammanfaller med datatyper i algoritmspråken C och Fortran. Dessutom har MPI möjligheten att skapa nytt härledda typer data för en mer exakt och kortfattad beskrivning av innehållet i vidarebefordrade meddelanden.

En detaljerad diskussion om MPI:s möjligheter att arbeta med härledda datatyper kommer att utföras i underavsnitt 5.5.

5.1.5. Virtuella topologier

Som noterats tidigare kan parade dataöverföringsoperationer utföras mellan alla processer hos samma kommunikatör, och alla processer hos kommunikatören deltar i en kollektiv operation. I detta avseende har den logiska topologin för kommunikationslinjer mellan processer strukturen av en komplett graf (oavsett närvaron av verkliga fysiska kommunikationskanaler mellan processorer).

Samtidigt (och detta noterades redan i avsnitt 3), för presentation och efterföljande analys av ett antal parallella algoritmer, är det tillrådligt att ha en logisk representation av det befintliga kommunikationsnätverket i form av vissa topologier.

MPI har förmågan att representera flera processer i formuläret galler godtycklig dimension (se underavsnitt 5.7). I detta fall kan gränsprocesserna för gitter deklareras angränsande och därmed, baserat på gittren, strukturer av typen torus.

Dessutom har MPI verktyg för att generera logiska (virtuella) topologier av vilken typ som helst. En detaljerad diskussion om MPI:s förmåga att arbeta med topologier kommer att utföras i underavsnitt 5.7.

Och till sist, en sista uppsättning anteckningar innan du börjar titta på MPI:

  • Beskrivningar av funktioner och alla exempel på program som tillhandahålls kommer att presenteras på algoritmspråket C; funktioner för att använda MPI för det algoritmiska språket Fortran kommer att ges i avsnitt 5.8.1,
  • En kort beskrivning av tillgängliga implementeringar av MPI-bibliotek och en allmän beskrivning av exekveringsmiljön för MPI-program kommer att diskuteras i avsnitt 5.8.2.
  • Huvudpresentationen av MPI-kapacitet kommer att fokusera på version 1.2-standarden ( MPI-1); ytterligare egenskaper för version 2.0-standarden kommer att presenteras i avsnitt 5.8.3.

När man börjar studera MPI kan det noteras att MPI å ena sidan är ganska komplext - MPI-standarden tillhandahåller närvaron av mer än 125 funktioner. Å andra sidan är strukturen för MPI noggrant genomtänkt - utvecklingen av parallella program kan börja efter att ha övervägt endast 6 MPI-funktioner. Alla ytterligare funktioner i MPI kan bemästras när komplexiteten hos de utvecklade algoritmerna och programmen ökar. Det är i denna stil – från enkel till komplex – som allt utbildningsmaterial om MPI kommer att presenteras vidare.

5.2. Introduktion till parallell programutveckling med hjälp av MPI

5.2.1. Grunderna i MPI

Låt oss presentera den minsta nödvändiga uppsättningen av MPI-funktioner, tillräcklig för utveckling av ganska enkla parallella program.

5.2.1.1 Initiering och avslutande av MPI-program

Första funktionen anropad MPI ska vara en funktion:

int MPI_Init (int *agrc, char ***argv);

för att initiera MPI-programexekveringsmiljön. Funktionsparametrarna är antalet argument på kommandoraden och texten på själva kommandoraden.

Senaste anropade funktionen MPI måste vara en funktion:

int MPI_Finalize(void);

Som ett resultat kan det noteras att strukturen för ett parallellprogram utvecklat med MPI bör ha följande form:

#include "mpi.h" int main (int argc, char *argv) (<программный код без использования MPI функций>MPI_Init(&agrc, &argv);<программный код с использованием MPI функций>MPI_Finalize();<программный код без использования MPI функций>returnera 0; )

Det bör noteras:

  1. Fil mpi.h innehåller definitioner av namngivna konstanter, funktionsprototyper och datatyper för MPI-biblioteket,
  2. Funktioner MPI_Init Och MPI_Finaliseraär obligatoriska och måste köras (och endast en gång) av varje process i det parallella programmet,
  3. Innan samtalet MPI_Init funktionen kan användas MPI_initialiserad för att avgöra om ett samtal har gjorts tidigare MPI_Init.

Exemplen på funktioner som diskuterats ovan ger en uppfattning om syntaxen för att namnge funktioner i MPI. Funktionsnamnet föregås av MPI-prefixet, följt av ett eller flera ord i namnet, det första ordet i funktionsnamnet börjar med ett stort tecken och orden separeras med ett understreck. Namnen på MPI-funktioner förklarar som regel syftet med de åtgärder som utförs av funktionen.

Det bör noteras:

  • Meddelare MPI_COMM_WORLD, som nämnts tidigare, skapas som standard och representerar alla processer i det parallella programmet som körs,
  • Rang som erhålls med funktionen MPI_Comm_rank, är rangordningen för den process som gjorde anropet till denna funktion, dvs. variabel ProcRank kommer att ha olika värderingar i olika processer.

Den här noteringen visar hur du installerar MPI, ansluter den till Visual Studio och sedan använder den med de angivna parametrarna (antal beräkningsnoder). Den här artikeln använder Visual Studio 2015, eftersom... Det här är den som mina elever hade problem med (denna anteckning skrevs av elever för elever), men instruktionerna kommer förmodligen att fungera för andra versioner också.

Steg 1:
Du måste installera HPC Pack 2008 SDK SP2 (i ditt fall kan det redan finnas en annan version), tillgänglig på den officiella Microsoft-webbplatsen. Bitkapaciteten för paketet och systemet måste matcha.

Steg 2:
Du måste konfigurera sökvägarna för att göra detta, gå till fliken Debug - Properties:

"C:\Program Files\Microsoft HPC Pack 2008 SDK\Include"

I fältet Bibliotekskataloger:

"C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\amd64"

I biblioteksfältet, om det finns en 32-bitarsversion, måste du ange i386 istället för amd64.

Msmpi.lib

:

Steg 3:

För att konfigurera lanseringen måste du gå till fliken Debugging och i kommandofältet ange:

"C:\Program Files\Microsoft HPC Pack 2008 SDK\Bin\mpiexec.exe"

I fältet Kommandoargument anger du t.ex.

N 4 $(TargetPath)

Siffran 4 anger antalet processer.

För att köra programmet måste du ansluta biblioteket

Sökvägen till projektet får inte innehålla kyrilliska. Om fel uppstår kan du använda Microsoft MPI, tillgängligt på Microsofts webbplats.

För att göra detta, efter installationen, skriv bara in sökvägen i kommandofältet på fliken Debugging:

"C:\Program Files\Microsoft MPI\Bin\mpiexec.exe"

Innan du kör programmet, glöm inte att ange dess bitdjup:

Exempel på att köra ett program med MPI:

#omfatta #omfatta använder namnutrymme std; int main(int argc, char **argv) ( int rank, storlek; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); cout<< "The number of processes: " << size << " my number is " << rank << endl; MPI_Finalize(); return 0; }

Kör programmet på 2 noder: