MPI Envoyez et recevez des questions

J’ai des questions sur les opérations d’envoi et de réception de MPI.

Supposons que 2 threads MPI essaient de s’envoyer un message. Voici trois extraits de code faisant cela:

D’abord (bloquer ‘envoyer’ et ‘recevoir’):

... int data = ...; ... MPI_Send( &data, sizeof( int ), MPI_INT, (my_id == 0)?1:0, 0, MPI_COMM_WORLD ); MPI_Status status; MPI_Recv( &data, sizeof( int ), MPI_INT, (my_id == 0)?1:0, 0, MPI_COMM_WORLD, &status ); ... 

Seconde (‘envoyer’ non bloquant mais bloquer ‘recevoir’):

 ... int data = ...; ... MPI_Request request; MPI_Isend( &data, sizeof( int ), MPI_INT, (my_id == 0)?1:0, 0, MPI_COMM_WORLD, &request); MPI_Status status; MPI_Recv( &data, sizeof( int ), MPI_INT, (my_id == 0)?1:0, 0, MPI_COMM_WORLD, &status ); // Synchronize sender & receiver MPI_Wait( &request, &status); ... 

Troisième (“recevoir” non bloquant avec “envoyer” bloquant):

 ... int data = ...; ... MPI_Request request; MPI_Irecv( &data, sizeof( int ), MPI_INT, (my_id == 0)?1:0, 0, MPI_COMM_WORLD, &request ); MPI_Send( &data, sizeof( int ), MPI_INT, (my_id == 0)?1:0, 0, MPI_COMM_WORLD); MPI_Status status; // Synchronize sender & receiver MPI_Wait( &request, &status); ... 

Je suppose qu’il ya des problèmes avec le code supérieur à trois, mais je voudrais connaître votre opinion. J’ai donc les questions suivantes:

  1. Quels sont les problèmes (potentiels) (le cas échéant) avec les 3 codes indiqués ci-dessus?

  2. Lesquels des trois codes ci-dessus sont valides / corrects compte tenu de la norme MPI afin qu’elle puisse fonctionner avec toutes les implémentations MPI?

  3. Quelle est la meilleure façon (si ce n’est l’une des réponses ci-dessus, veuillez l’écrire) de le faire?

  4. Dans le troisième code, que se passe-t-il si nous changeons l’ordre des appels MPI_Irecv et MPI_Send?

PS: Au fait, j’ai essayé de les exécuter avec Scali MPI et tous ont fonctionné!

Votre première implémentation risque de provoquer un blocage, en particulier si la communication est effectuée en mode synchronisé (cela a peut-être fonctionné dans vos tests, car la communication a été mise en mémoire tampon; ce n’est probablement pas le cas pour des données volumineuses).

Les deux autres implémentations devraient fonctionner sans blocage. Je crois qu’il est considéré comme une meilleure pratique d’initier les opérations de réception avant les envois, je préférerais donc personnellement la troisième mise en œuvre. À partir de la norme MPI, section 3.7 :

Conseils aux utilisateurs

[…]

Le modèle de transmission de message implique que la communication est initiée par l’expéditeur. La communication aura généralement moins de temps système si une réception est déjà enregistrée lorsque l’expéditeur initie la communication (les données peuvent être déplacées directement dans la mémoire tampon de réception et il n’est pas nécessaire de mettre en queue une demande d’envoi en attente). Toutefois, une opération de réception ne peut se terminer qu’après l’envoi correspondant. L’utilisation de la réception non bloquante permet de réduire les coûts de communication sans bloquer le récepteur pendant l’attente de l’envoi.

La troisième implémentation avec la commande MPI_Send / MPI_Irecv peut se MPI_Irecv dans l’appel MPI_Send pour les mêmes raisons que la première implémentation.