У меня проблема со связками в программе 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;
}
Я обновил свое сообщение, чтобы упомянуть, что я выполняю это только на одной машине, отключенной от Интернета, поэтому я не отслеживаю пакеты. Задержка обычно увеличивается на 100% за время, затрачиваемое на отчет о первой победе. Любой процесс, выходящий из цикла do..while, предполагает, что они выиграли и проверяют только локально, если они выиграли (без межпроцессного взаимодействия). Я могу справиться с связями, но задержка является проблематичной. –
Я опубликовал другое обновление, существенно уменьшающее мои задержки, однако я все еще ищу совет по системе сообщений о выходе, которую я использую. –
Подумайте, какие сообщения вы должны отправить. Как минимум, я думаю, победа, подтверждение и выход. Кроме того, вам нужно решить, кто отправляет сообщение о выходе. Возможно, вы захотите записать результаты от всех детей, поэтому решите, записывает ли каждый из них свои результаты или результаты основных записей. Насколько жесткой вы хотите сигнализировать? Если у вас есть несколько человек, отправьте «выигрыш» сейчас, каждый отправит бросить курить всем.победитель 'confirm' позволил бы первому победителю отправить бросок. – ChuckCottrill