2016-04-27 8 views
0

Wenn ein anderer Prozess einen anderen Wert an die anderen Prozesse in der Gruppe eines bestimmten Kommunikators sendet, was würde passieren?Könnte MPI_Bcast zum Problem der Datenunsicherheit führen?

Nehmen Sie das folgende Programm durch zwei Prozesse als Beispiel läuft,

int rank, size; 
int x; 
MPI_Init(&argc, &argv); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
if (rank == 0) 
{ 
    x = 0; 
    MPI_Bcast(&x, 1, MPI_INT, 0, MPI_COMM_WORLD); 
} 
else if (rank==1) 
{ 
    x = 1; 
    MPI_Bcast(&x, 1, MPI_INT, 1, MPI_COMM_WORLD); 
} 
cout << "Process " << rank << "'s value is:" << x << endl; 
MPI_Finalize(); 

Ich denke, es am Ende des Programms verschiedene Möglichkeiten des gedruckten Ergebnisses sein könnte. Wenn der Prozess 0 schneller als Prozess 1 ausgeführt wird, sendet er seinen Wert früher als Prozess 1, so dass Prozess 1 den gleichen Wert mit Prozess 0 hat, wenn er beginnt, seinen Wert zu senden, wodurch der gedruckte Wert von x zu 0 wird Der Prozess 0 läuft langsamer als Prozess 1, der Prozess 0 hat den gleichen Wert wie Prozess 1, der am Ende 1 ist. Ist das, was ich beschrieben habe, tatsächlich passiert?

+1

Genau genommen ist dieser Code nicht konform, da nicht alle Prozesse des Communicators 'MPI_Bcast()' mit dem gleichen Wurzelargument aufrufen (was vom MPI-Standard explizit gefordert wird). Daher ist das Verhalten nicht definiert: Alles kann passieren. – Gilles

Antwort

1

Ich denke, Sie verstehen die MPI_Bcast-Funktion nicht gut. Tatsächlich ist MPI_Bcast eine Art von kollektiver MPI-Kommunikationsmethode, bei der jeder Prozess, der zu einem bestimmten Kommunikator gehört, einbezogen werden muss. Für die Funktion von MPI_Bcast muss daher nicht nur der Prozess, der die zu sendenden Daten sendet, sondern auch die Prozesse, die die gesendeten Daten empfangen, die Funktion synchron aufrufen, um das Ziel der Datenübertragung zwischen allen beteiligten Prozessen zu erreichen.

In Ihrem bestimmten Programm, vor allem dieses Teil:

if (rank == 0) 
{ 
    x = 0; 
    MPI_Bcast(&x, 1, MPI_INT, 0, MPI_COMM_WORLD); 
} 
else if (rank==1) 
{ 
    x = 1; 
    MPI_Bcast(&x, 1, MPI_INT, 1, MPI_COMM_WORLD); 
} 

Ich glaube, du Prozess Rang deren lassen gemeint ist 0 (Prozess 0) sendet seinen Wert von x zu anderen Prozessen, aber in Ihrem Code, nur Der Prozess 0 ruft die Funktion MPI_Bcast auf, wenn Sie das Segment if-else verwenden. Was machen andere Prozesse? Für einen Prozess, dessen Rang 1 ist (Prozess 1), ruft er nicht dieselbe MPI_Bcast-Funktion auf, die der Prozess 0 aufruft, obwohl er eine andere MPI_Bcast-Funktion aufruft, um seinen Wert von x zu übertragen (das Argument von root unterscheidet zwischen diesen beiden MPI_Bcast-Funktionen) Wenn also nur der Prozess 0 die Funktion MPI_Bcast aufruft, sendet er nur den Wert von x an sich selbst und der in anderen Prozessen gespeicherte Wert von x wird überhaupt nicht beeinflusst. Es ist auch die gleiche Bedingung für Prozess 1. Als Ergebnis in Ihrem Programm sollte der gedruckte Wert von x für jeden Prozess der gleiche sein wie wenn er anfänglich zugewiesen wurde und es nicht die Datenunsicherheit geben würde, die Sie betreffen.

1

MPI_Bcast wird in erster Linie verwendet, damit der Rang 0 [root] Werte berechnen und übertragen kann, so dass jeder mit den gleichen Werten beginnt.

Hier ist eine gültige Nutzung:

int x; 

// not all ranks may get the same time value ... 
srand(time(NULL)); 

// so we must get the value once ... 
if (rank == 0) 
    x = rand(); 

// and broadcast it here ... 
MPI_Bcast(&x,1,MPI_INT,0,MPI_COMM_WORLD); 

Beachten Sie den Unterschied aus Ihrer Nutzung. Die gleicheMPI_Bcast Anruf für alle Ränge. Die Wurzel wird senden und die anderen werden recv.

Verwandte Themen