2013-10-04 26 views
0

我有一個C/C++ MPI程序中的關係問題,它模擬在所有進程中玩遊戲。如果任何進程獲勝(包括主進程),那麼進程應該告訴所有其他進程停止玩他們的遊戲,以便結果可以發送給主進程並由主進程進行總計。允許任何進程發送退出消息

問題是我有時會在獲勝的過程中獲得一個或多個過程,說他們首先獲勝。這會在結束之前導致漫長的持續時間(在某些情況下超過一分鐘)。我不知道我是否正在處理所有進程之間的退出消息情況。

UPDATE:該程序在單臺機器上運行,而不是通過網絡運行。該機器不在互聯網上。

UPDATE 2:由於內部遊戲代碼導致操作太多,我能夠大幅減少延遲問題。我仍在尋找關於我使用Irecv/Isend退出進程的方式的解釋。

UPDATE 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

我解決了我的問題。我不再得到延遲,問題是我的遊戲程序邏輯本身。 processSlave for循環已被修改爲具有另一個條件pID != rank,該條件打破了在發送TAG_QUIT消息時導致進程被跳過的邏輯。

0

'win'包的Wireshark/ethereal時機? '優勝者'之間有多少延遲? 協議允許多個客戶說'贏',但客戶是否認爲他們'贏',或等待確認?

你的消息協議是什麼?你在幾個地方顯示'TAG_QUIT'。怎麼樣,

  • 孩子信號與「贏」
  • 父母信號孩子家長與「確認」
  • 贏得孩子信號別的孩子「退出」(幸災樂禍)
  • 或者,父母信號的其它兒童與「退出」
  • 失去子女可能預示着「贏」(失敗種族,延遲)
  • 父信號丟失/晚的孩子與「失去」或「不合格」
+0

我更新了我的帖子,提到我只在單臺機器上運行,與互聯網斷開連接,所以我不跟蹤數據包。在報告第一場勝利時,延遲通常會增加100%。任何退出do..while循環的進程都會假設他們贏了,並且只在本地贏得比賽(沒有進程間通信)。我可以處理關係,但延遲是有問題的。 –

+0

我發佈了另一個更新,大大減少了我的延遲,但是我仍然在尋找關於我正在使用的退出消息系統的建議。 –

+0

想想你應該發送什麼消息。至少,我認爲勝利,確認並放棄。另外你需要決定誰發送退出信息。您可能想要記錄所有孩子的成績,因此請決定每個孩子是否記錄其成績,或者主記錄成績。你想要信號有多緊?如果你現在有幾個人發送'勝利',他們每個人都會退出給所有人。一個'確認'獲勝者將允許第一個贏家發送戒菸。 – ChuckCottrill