我給你回的開放MPI的用戶列表中,同時也將它張貼在這裏,萬一有人覺得它有用。我相信Jeff Squyres已經在Open MPI郵件列表上回答了您的問題,或者至少暗示了可能存在的問題。 MPI消息按它們發送的順序接收,但只在特定的(標記,通信器)元組內。這基本上意味着:
- 在同一個通訊器中,如果它們攜帶不同的標籤,您可以接收不按順序的消息;
- 攜帶相同標籤的消息如果在不同的上下文(通信器)中進行通信,可能會被無序接收。
但是,這裏有一個問題:如果發送操作尚未發佈,您將無法收到消息。如果你有兩個連續的發送操作,你必須確保第一個不會永遠阻塞。標準的MPI發送操作MPI_Send
可以以各種方式實現(標準沒有詳細說明如何),但是在大多數MPI實現中,它的行爲類似緩衝發送非常小的消息,並且像大型消息的同步發送。如果你在你發送過程中的以下兩個調用:
MPI_Send(largedata, largecount, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(smalldata, smallcount, MPI_INT, dest, tag2, MPI_COMM_WORLD);
是可能發生的第一MPI_Send
實際上表現爲一個同步,也就是說,它不會返回,除非匹配的接收操作被張貼在接收方。假設你的接收器的代碼是:
MPI_Probe(src, tag2, MPI_COMM_WORLD, &status);
MPI_Recv(largedata, largecount, MPI_INT, src, tag1, MPI_COMM_WORLD, &status);
這很可能會陷入僵局,因爲MPI_Probe
是一個阻塞調用,也就是說,它不會返回,直到匹配發送被張貼,即第二MPI_Send
就必須執行,這不僅會在第一次發送返回後發生,但除非接收器中的MPI_Recv
正在執行,否則不會發生。我猜你的想法
爲了防止你可以修改發送方的代碼僵局使用非阻塞發送:
MPI_Request req;
MPI_Isend(largedata, largecount, MPI_INT, dest, tag1, MPI_COMM_WORLD, &req);
MPI_Send(smalldata, smallcount, MPI_INT, dest, tag2, MPI_COMM_WORLD);
MPI_Wait(&req, MPI_STATUS_IGNORE);
立即發送調用返回使用非阻塞操作和操作繼續背景,所以第二次發送會在那之後立即執行。現在會有兩個待處理的消息,並且它們可以以任何順序接收,因爲它們攜帶不同的標籤。
非常感謝Iliev!我錯過了傑夫的回答,這太簡潔了。這更有幫助! –
不客氣。令人遺憾的是,官方和長期運行的郵件列表被Web 2.0技術所掩蓋,但這似乎是未來... –