2013-10-04 3 views
0

У меня проблема со связками в программе CI/C++ MPI, которая имитирует игру во всех процессах. Если какой-либо процесс побеждает, включая мастер, этот процесс должен рассказать всем остальным процессам о выходе из игры, чтобы результаты могли быть отправлены и суммированы мастером.Позволяет любому процессу отправить сообщение о выходе

Проблема в том, что я иногда получаю 1 или более процессов поверх выигрышного процесса, заявляя, что они выиграли в первую очередь. Это приводит к длительной зависанию (в некоторых случаях более чем за минуту) до окончания. Я не уверен, правильно ли я обрабатываю ситуацию с отправкой сообщений между всеми процессами.

ОБНОВЛЕНИЕ: Эта программа работает на одной машине, а не по сети. Машина не в Интернете.

UPDATE 2: Я смог существенно уменьшить проблему задержки из-за внутреннего игрового кода, вызывающего слишком много операций. Я все еще ищу интерпретацию того, как я использую Irecv/Isend для выхода из процессов.

ОБНОВЛЕНИЕ 3: Найдена моя проблема, указанная в моем ответе.

Вот несколько примеров из моего приложения, чтобы помочь.

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; 
} 

ответ

0

Я исправил свою проблему. Я больше не получаю задержки, и проблема была сама логика игровой программы. Процесс processllave for loop был изменен, чтобы иметь другое условие pID != rank, которое нарушило логику, вызывающую пропуски процессов при отправке сообщения TAG_QUIT.

0

Wireshark/эфирное время «выигрывать» пакеты? Сколько задержек между «победителями»? Протокол позволяет нескольким клиентам говорить «выиграть», но клиент предполагает, что они «выиграли» или ждут подтверждения?

Каков ваш протокол сообщений? Вы показываете «TAG_QUIT» в нескольких местах. Как насчет того,

  • ребенок сигнализирует родитель с «Win»
  • родительских сигналов ребенком с «Confirm»
  • победой ребенком сигналы других детьми «Quit» (злорадством)
  • или, родительские сигналы других детей с «Выход»
  • потери ребенка (детей), может сигнализировать «Win» (провал из-за расы, задержки)
  • родитель сигналы проигрышная/поздний ребенок с «потерять» или «Сбой»
+0

Я обновил свое сообщение, чтобы упомянуть, что я выполняю это только на одной машине, отключенной от Интернета, поэтому я не отслеживаю пакеты. Задержка обычно увеличивается на 100% за время, затрачиваемое на отчет о первой победе. Любой процесс, выходящий из цикла do..while, предполагает, что они выиграли и проверяют только локально, если они выиграли (без межпроцессного взаимодействия). Я могу справиться с связями, но задержка является проблематичной. –

+0

Я опубликовал другое обновление, существенно уменьшающее мои задержки, однако я все еще ищу совет по системе сообщений о выходе, которую я использую. –

+0

Подумайте, какие сообщения вы должны отправить. Как минимум, я думаю, победа, подтверждение и выход. Кроме того, вам нужно решить, кто отправляет сообщение о выходе. Возможно, вы захотите записать результаты от всех детей, поэтому решите, записывает ли каждый из них свои результаты или результаты основных записей. Насколько жесткой вы хотите сигнализировать? Если у вас есть несколько человек, отправьте «выигрыш» сейчас, каждый отправит бросить курить всем.победитель 'confirm' позволил бы первому победителю отправить бросок. – ChuckCottrill

Смежные вопросы