すべてのプロセスでゲームのプレイをシミュレートする C/C++ MPI プログラムのタイに問題があります。マスターを含むいずれかのプロセスが勝った場合、そのプロセスは他のすべてのプロセスにゲームのプレイを終了するように指示し、結果をマスターに送信して合計できるようにする必要があります。
問題は、最初に勝ったと言って、勝ったプロセスの上に1つ以上のプロセスが表示されることがあります。これにより、終了する前に長いハング (場合によっては 1 分以上) が発生します。すべてのプロセス間で終了メッセージの状況を適切に処理しているかどうかはわかりません。
更新: このプログラムは、ネットワーク経由ではなく、単一のマシンで実行されています。マシンがインターネットに接続されていません。
更新 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;
}