En paires MPI_Send / MPI_Recv, les données peuvent être perdues si elle n'est pas synchronisé correctement?
-
27-09-2019 - |
Question
Laissez-moi vous expliquer. 4 nœuds de considérer esclaves 1, 2, 3, 4 et un noeud maître 0. Maintenant, 1, 2, 3, 4, besoin d'envoyer des données à 0. 0 reçoit ces données dans le format suivant.
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 2 ne transmet ses données avant 1 (par exemple), la boucle de réception de 0 ci-dessus ne déclenche pas jusqu'à ce que le point source « proc » dans la commande MPI_Recv adapté au processeur « 1 », car la partie extérieure des forces de boucle cet ordre.
Alors qu'est-ce qui se passe est la boucle « attend » jusqu'à ce qu'il y a des données entrantes de 1 avant de pouvoir faire quoi que ce soit d'autre, même s'il y a déjà des données en provenance de 2, 3 et 4. Qu'advient-il de ces données arrivant de 2,3 et 4 si elle arrive avant 1? Peut-il être « oubliés » dans le sens où une fois les données de « 1 » ne commencent à arriver, puis par incréments proc à 2, les données qu'il initialement tenté de recevoir 2 est tout simplement pas là plus? Si elle est « oubliée », la simulation distribuée tout va simplement passer, parce qu'il ne finit jamais par être en mesure de traiter les données d'un processus esclave particulier correctement.
Merci, Ben.
La solution
Tout d'abord, avez-vous vraiment moyen de recevoir un MPI_CHAR
dans chunkP - un int
- ne devrait pas vous recevoir un MPI_INT
Les messages de rangs 1: 4 ne seront pas perdus - ils seront en file d'attente jusqu'à ce rang 0 choisit de les recevoir. Ce comportement est mandaté par la norme MPI.
Si les messages sont assez grandes, classe 1: 4 peut bloquer jusqu'à ce qu'ils puissent envoyer réellement leurs messages à rang 0 (la plupart des implémentations de MPI ont en mémoire tampon limitée).
Vous pouvez également envisager de rang 0 faire une MPI_ANY_SOURCE
recevoir pour la première réception pour voir qui est prêt à envoyer. Vous aurez besoin de prendre soin que pour faire en sorte que REÇOIT ultérieures sont enregistrées pour la source correspondante -. Regard dans le struct MPI_Status
pour voir où le message a été effectivement envoyé par