0

我在模拟跨所有进程玩游戏的 C/C++ MPI 程序中存在关联问题。如果任何进程获胜,包括 master,该进程应该告诉所有其他进程退出游戏,以便结果可以发送给 master 并由 master 汇总。

问题是我有时会在获胜进程之上获得 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;
}
4

2 回答 2

0

'win'数据包的Wireshark / ethereal时间?“赢家”之间有多少延迟?协议允许多个客户说“赢”,但客户是否认为他们“赢了”,或者等待确认?

你的消息协议是什么?您在几个地方显示“TAG_QUIT”。怎么样,

  • 孩子用“Win”向父母发出信号
  • 父母用“确认”向孩子发出信号
  • 获胜的孩子用“退出”(幸灾乐祸)向其他孩子发出信号
  • 或者,父母向其他孩子发出“退出”的信号
  • 失去孩子可能表示“胜利”(由于比赛、延误而失败)
  • 父母用“失败”或“失败”表示失去/迟到的孩子
于 2013-10-04T02:20:46.667 回答
0

我解决了我的问题。我不再有延迟,问题是我的游戏程序逻辑本身。processSlave for 循环已被修改为具有另一个条件,该条件pID != rank破坏了导致在发送 TAG_QUIT 消息时跳过进程的逻辑。

于 2013-10-04T06:59:56.187 回答