2013-10-04 3 views
0

J'ai un problème avec les liens dans un programme MPI C/C++ qui simule la lecture d'un jeu dans tous les processus. Si un processus gagne, y compris le maître, ce processus devrait dire à tous les autres processus de quitter leur jeu afin que les résultats puissent être envoyés et totalisés par le maître. Le problème est que je reçois parfois 1 ou plusieurs processus en plus du processus gagnant en disant qu'ils ont gagné en premier. Il en résulte un long accrochage (bien plus d'une minute dans certains cas) avant la fin. Je ne suis pas sûr si je gère la situation de message de quitter correctement entre tous les processus.Autoriser un processus à envoyer un message de fermeture

MISE À JOUR: Ce programme s'exécute sur une machine unique, pas sur un réseau. La machine n'est pas sur internet.

MISE À JOUR 2: J'ai été en mesure de réduire considérablement le problème de délai en raison du code de jeu interne causant trop d'opérations. Je suis toujours à la recherche d'une interprétation de la façon dont j'utilise Irecv/Isend pour quitter les processus.

MISE À JOUR 3: J'ai trouvé mon problème, affiché dans ma réponse.

Voici un code de mon application pour aider.

int max_streak_length; // set in main from argv[], greater than 0 
bool should_quit = false; 

void checkMessages() 
{ 
    static int recvFlag 
    static bool msgBuff; 
    static MPI_Request request; 
    MPI_Status status; 

    // Are we already listening 
    if(request) 
    { 
     // Test for message 
     MPI_Test(&request, &recvFlag, &status); 

     if(recvFlag) 
     { 
      if(status.MPI_TAG == TAG_QUIT) 
       should_quit = true; 
     } 
    } 

    // Start listening if we aren't 
    if(!request) 
     MPI_Irecv(&msgBuff, 1, MPI_C_BOOL, MPI_ANY_SOURCE, TAG_QUIT, MPI_COMM_WORLD, &request); 
} 

void processMaster(int numProcs) { 
    double start = MPI_Wtime(); 
    Game game(max_streak_length); 

    do 
    { 
     if(numProcs > 1) 
      checkMessages(); 
     game.play(); 
    } while(!should_quit && !game.is_game_over()); 

    // Let other processes know they should stop, if I won 
    if(!should_quit && game.is_game_over()) 
    { 
     cout << "Master wins " << MPI_Wtime() << endl; 
     for(int pID = 1; numProcs > 1 && pID < numProcs; ++pID) 
     { 
      MPI_Request r; 
      MPI_Isend(&should_quit, 1, MPI_C_BOOL, pID, TAG_QUIT, MPI_COMM_WORLD, &r); 
     } 
    } 

    cout << "master quitting" << endl; 
} 

void processSlave(int numProcs, int rank) { 
    Game game(max_streak_length); 

    do 
    { 
     checkMessages(); 
     game.play(); 
    } while(!should_quit && !game.is_game_over()); 

    // Let other processes know they should stop, if I won 
    if(!should_quit && game.is_game_over()) 
    { 
     cout << rank << " wins " << MPI_Wtime() << endl; 
     for(int pID = 0; pID < numProcs; ++pID) 
     { 
      if(pID == rank) 
       continue; 
      MPI_Request r; 
      MPI_Isend(&should_quit, 1, MPI_C_BOOL, pID, TAG_QUIT, MPI_COMM_WORLD, &r); 
     } 
    } 

    cout << rank << " quitting" << endl; 
} 

Répondre

0

J'ai corrigé mon problème. Je n'ai plus du tout les retards, et le problème était ma logique de programme de jeu elle-même. La boucle processSlave for a été modifiée pour avoir une autre condition pID != rank qui a brisé la logique provoquant l'annulation des processus lors de l'envoi du message TAG_QUIT.

0

Wireshark/synchronisation éthérée des paquets «win»? Combien de temps entre les «gagnants»? Le protocole permet à plusieurs clients de dire «gagner», mais le client suppose-t-il qu'il a «gagné» ou qu'il attend une confirmation?

Quel est votre protocole pour les messages? Vous montrez 'TAG_QUIT' dans quelques endroits. Que diriez-vous,

  • enfant signaux parent avec des signaux parent 'Win'
  • enfant 'Confirmer'
  • gagner des signaux d'enfants d'autres enfants avec 'Quitter' (jubiler)
  • ou, signaux de parents d'autres enfants avec « Quitter »
  • enfant perdu (s) peut signaler « Win » (échec en raison de la race, des retards)
  • signaux parent perdant/enfant fin « perdre » ou « échec »
+0

J'ai mis à jour mon message pour indiquer que je ne l'utilise que sur une seule machine, déconnectée d'Internet, donc je ne fais pas de suivi des paquets. Le retard est généralement une augmentation de 100% sur le temps qu'il a fallu pour signaler la première victoire. Tout processus sortant de la boucle do..while suppose qu'il a gagné et ne vérifie localement que s'il a gagné (pas de communication inter-processus). Je peux gérer les liens, mais le retard est problématique. –

+0

J'ai posté une autre mise à jour réduisant considérablement mes retards, mais je suis toujours à la recherche de conseils sur le système de messagerie que j'utilise. –

+0

Pensez aux messages que vous devriez envoyer. Au minimum, je pense gagner, confirmer et quitter. De plus, vous devez décider qui envoie le message d'abandon. Vous pouvez enregistrer les résultats de tous les enfants, alors décidez si chaque enfant enregistre ses résultats ou les résultats de la fiche principale. À quel point voulez-vous la signalisation? Si vous envoyez plusieurs 'win' maintenant, ils enverront chacun à quit à tout le monde.un gagnant «confirme» permettrait au premier gagnant d'envoyer le départ. – ChuckCottrill

Questions connexes