web-dev-qa-db-fra.com

Quand dois-je utiliser MPI_Barrier ()?

Je me demande quand dois-je utiliser une barrière? En ai-je besoin avant/après un scatter/rassemblement par exemple? Ou OMPI devrait-il s'assurer que tous les processus ont atteint ce point avant la dispersion/la collecte? De même, après une diffusion, puis-je m'attendre à ce que tous les processus reçoivent déjà le message?

28
Jiew Meng

Toutes les opérations collectives dans MPI avant MPI-3.0 sont bloquées, ce qui signifie qu'il est sûr d'utiliser tous les tampons qui leur sont passés après leur retour. En particulier, cela signifie que toutes les données ont été reçues lorsqu'une de ces fonctions renvoie. (Cependant, cela n'implique pas que toutes les données ont été envoyées!) Donc MPI_Barrier n'est pas nécessaire (ou très utile) avant/après les opérations collectives, si tous les tampons sont déjà valides.

Veuillez également noter que MPI_Barrier n'attend pas comme par magie les appels non bloquants. Si vous utilisez un envoi/recv non bloquant et que les deux processus attendent sur un MPI_Barrier après la paire d'envoi/recv, il n'est pas garanti que les processus ont envoyé/reçu toutes les données après le MPI_Barrier. Utilisez plutôt MPI_Wait (et vos amis). Ainsi, le morceau de code suivant contient des erreurs:

/* ERRORNOUS CODE */

Code for Process 0:
Process 0 sends something using MPI_Isend
MPI_Barrier(MPI_COMM_WORLD);
Process 0 uses buffer passed to MPI_Isend // (!)

Code for Process 1:
Process 1 recvs something using MPI_Irecv
MPI_Barrier(MPI_COMM_WORLD);
Process 1 uses buffer passed to MPI_Irecv // (!)

Les deux lignes marquées par (!) sont dangereux!

MPI_Barrier n'est utile que dans une poignée de cas. La plupart du temps, peu vous importe que vos processus se synchronisent. Mieux lire sur les appels bloquants et non bloquants!

25
Markus Mayr

Une utilisation de MPI_Barrier est par exemple pour contrôler l'accès à une ressource externe telle que le système de fichiers, qui n'est pas accessible en utilisant MPI. Par exemple, si vous voulez que chaque processus écrive des trucs dans un fichier en séquence, vous pouvez le faire comme ceci:

int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for ( int ii = 0; ii < size; ++ii ) {
    if ( rank == ii ) {
        // my turn to write to the file
        writeStuffToTheFile();
    }
    MPI_Barrier(MPI_COMM_WORLD);
}

De cette façon, vous pouvez être sûr qu'il n'y a pas deux processus appelant simultanément writeStuffToTheFile.

15
Edric

Mai MPI_Barrier () n'est pas souvent utilisé, mais il est utile. En fait, même si vous utilisiez la communication synchrone, MPI_Send/Recv () ne peut que s'assurer que les deux processus sont synchronisés. Dans mon projet, un projet cuda + MPI, je n'ai utilisé que la communication asynchrone. J'ai trouvé que dans certains cas, si je n'utilise pas la fonction MPI_Barrier () suivie de la fonction Wait (), la situation selon laquelle deux processus (GPU) souhaitent se transmettre des données en même temps est très susceptible de se produire, ce qui pourrait mal réduire l'efficacité du programme. Le bug ci-dessus me plonge jamais fou et me prend quelques jours pour le trouver. Par conséquent, vous pouvez réfléchir attentivement à l'utilisation de MPI_Barrier () lorsque vous avez utilisé MPI_Isend/Irecv dans votre programme. Parfois, la synchronisation des processus est non seulement nécessaire, mais DOIT également, en particulier votre programme traite avec le périphérique.

0
Freezenfire