我在C / C ++ MPI程序中存在一个问题,它模拟在所有进程中玩游戏。如果任何进程获胜,包括master,该进程应告诉所有其他进程退出其游戏,以便结果可以发送给master并由master进行总计。
问题是我有时会在获胜过程中获得一个或多个进程,说他们先赢了。这导致在完成之前长时间悬挂(在某些情况下超过一分钟)。我不确定我是否在所有进程之间正确处理退出消息的情况。
更新:此程序在单台计算机上运行,而不是在网络上运行。机器不在互联网上。
更新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 :(得分:0)
'赢'包的Wireshark / ethereal时间? “赢家”之间有多少延迟? 协议允许多个客户说“赢”,但客户是否认为他们“赢了”,或等待确认?
您的邮件协议是什么?你在几个地方展示'TAG_QUIT'。怎么样,
答案 1 :(得分:0)
我解决了我的问题。我根本不再得到延迟,问题在于我的游戏程序逻辑本身。 processSlave for循环已被修改为具有另一个条件pID != rank
,该条件在发送TAG_QUIT消息时打破了导致跳过的逻辑。