2010-11-24 47 views
1

Laissez-moi vous expliquer. Considérons 4 nœuds esclaves 1, 2, 3, 4 et un nœud maître 0. Maintenant, 1, 2, 3, 4, doivent envoyer des données à 0. 0 reçoit ces données dans le format suivant.Dans les paires MPI_Send/MPI_Recv, les données peuvent-elles être perdues si elles ne sont pas synchronisées correctement?

for(int proc = 1;proc<procCount;proc++) // for each processor cpu (procCount = 5) 
{ 
    for(int p = 0;p<50;p++) 
    { 

    std::cout<<proc<<"\tA\t"<<p<<std::endl; 

    // read in binary datas 
    int chunkP; 
    int realP; 
    real fitnessVal; 
    real fitnessValB; 
    real fitnessValC; 
    int conCount; 
    real subConCount; 
    real networkEnergyLoss; 
    real movementEnergyLoss; 
    long spikeCount; 

    MPI_Recv (reinterpret_cast < char *>(&chunkP), 
     sizeof (chunkP), 
        MPI_CHAR,proc,MPI_ANY_TAG,MPI_COMM_WORLD,&stat); 
    MPI_Recv (reinterpret_cast < char *>(&realP), 
     sizeof (realP), 
         . 
         . 
         . 
      } 
    } 

Il est clair que l'ordre dans lequel 1, 2, 3 et 4 envoyer les données à 0 ne peut pas supposer (car ils fonctionnent tous indépendamment les uns des autres - 2 peut envoyer des données avant 1). Donc, en supposant que 2 envoie ses données avant 1 (par exemple), la boucle de réception de 0 montrée ci-dessus ne démarrera pas tant que la variable source 'proc' de la commande MPI_Recv ne correspondra pas au processeur '1' cette commande. Donc, ce qui se passe, c'est que la boucle attend que les données arrivent de 1 avant de pouvoir faire quoi que ce soit d'autre, même s'il y a déjà des données arrivant de 2, 3 et 4. Qu'est-ce qui arrive? et 4 s'il arrive avant 1? Peut-il être «oublié» dans le sens où une fois que les données de '1' commencent à arriver et que proc passe à 2, les données qu'il a essayé de recevoir à partir de 2 ne sont plus là? Si elle est «oubliée», toute la simulation distribuée va simplement se bloquer, car elle ne finit jamais par traiter correctement les données d'un processus esclave particulier.

Merci, Ben.

Répondre

3

Tout d'abord, voulez-vous vraiment recevoir un MPI_CHAR en chunkP - un int - ne devriez-vous pas recevoir un MPI_INT?

Les messages des rangs 1: 4 ne seront pas perdus - ils seront mis en file d'attente jusqu'à ce que le rang 0 choisisse de les recevoir. Ce comportement est mandaté par la norme MPI.

Si les messages sont suffisamment grands, les rangs 1: 4 peuvent bloquer jusqu'à ce qu'ils puissent réellement envoyer leurs messages au rang 0 (la plupart des implémentations MPI ont une mise en mémoire tampon limitée).

Vous pourriez également considérer avoir le rang 0 faire un MPI_ANY_SOURCE recevoir pour le premier recevoir pour voir qui est prêt à envoyer. Cependant, vous devrez faire attention à ce que les reçus suivants soient postés pour la source correspondante - regardez dans la structure MPI_Status pour voir d'où le message a réellement été envoyé.

+0

En fait, en ce qui concerne votre premier commentaire, non, je ne parle pas nécessairement de MPI_INT. Comme j'ai tellement de types de données différents à recevoir (y compris les flottants, les entiers, les booléens etc.), je préfère les recevoir tous comme MPI_CHAR puis les réinterpréter aux types de données requis. Pouvez-vous voir des problèmes avec cette méthode? ... merci aussi pour vos autres commentaires, je vais regarder la suggestion MPI_ANY_SOURCE. –

+0

Ah, je vois - dans ce cas, recevoir MPI_CHAR (ou même MPI_BYTE) est bien. – Edric