回答
阻止通信使用MPI_Send()
和MPI_Recv()
完成。這些功能不會返回(即阻塞)直到通信完成。簡化一下,這意味着傳遞給MPI_Send()
的緩衝區可以重用,因爲MPI將它保存在某處,或者因爲它已被目標接收。同樣,當接收緩衝區填充有效數據時,將返回MPI_Recv()
。
相反,非阻塞通信使用MPI_Isend()
和MPI_Irecv()
完成。即使通信尚未完成,這些功能立即返回(即,它們不阻止)。您必須致電MPI_Wait()
或MPI_Test()
查看通訊是否完成。
阻塞通信在使用時足夠使用,因爲使用起來更容易一些。必要時使用非阻塞通信,例如,您可以撥打MPI_Isend()
,做一些計算,然後做MPI_Wait()
。這允許計算和通信重疊,這通常導致改進的性能。
請注意,集體通信(例如all-reduce)僅在其阻止版本中可用,直到MPIv2。 IIRC,MPIv3引入了無阻塞的集體通信。
MPI發送模式的快速概覽可以看到here。
在使用阻擋通信,你必須關心發送和驗證碼
if(rank==0)
{
MPI_Send(x to process 1)
MPI_Recv(y from process 1)
}
if(rank==1)
{
MPI_Send(y to process 0);
MPI_Recv(x from process 0);
}
在這種情況下會發生什麼接收例如 看電話?
- 進程0將x發送到進程1並阻塞,直到進程1接收到x爲止。
- 進程1將y發送到進程0並阻塞,直到進程0接收到y,但是
- 進程0被阻塞,使得進程1阻塞無窮大,直到兩個進程被終止。
我曾經這麼認爲。但是當我在我的電腦上使用MPI_Send時,我發現裏面的問題可能會更復雜。上面的代碼可以將消息移動到緩衝區。只有'MPI_Ssend'嚴格禁止*,因爲它返回,直到目的地收到消息。以下鏈接解釋了不同的供應商選擇不同的實施。 http://www.mcs.anl.gov/research/projects/mpi/sendmode.html – 2015-05-25 12:20:27
這很容易。
非阻塞意味着計算和傳輸數據可能同時發生在單個進程中。
雖然阻止意味着,嘿,夥計,你必須確保你已經完成了數據傳輸,然後回到完成下一個命令,這意味着如果有一個轉移,然後計算,計算必須在成功的轉移。
它的酷感謝@Pab Peter – 2015-11-10 03:51:36
這篇文章雖然有點陳舊,但我堅持認可的答案。聲明「這些函數在通信完成之前不會返回」有點誤導,因爲阻塞通信不保證發送和接收操作之間的任何握手。
首先需要知道,發送方式有四種模式通信的:標準,緩衝,同步和就緒和每一種可以阻塞和無阻塞
不像發送,接收只有一個模式並可以阻止或非阻塞。
堵塞通信: 堵塞並不意味着消息已傳遞到接收器/目的地。它只是意味着(發送或接收)緩衝區可供重用。爲了重新使用緩衝區,將信息複製到另一個存儲區就足夠了,也就是說,庫可以將緩衝區數據複製到庫中的自己的存儲位置,然後例如MPI_Send可以返回。
MPI標準清楚地說明了從發送和接收操作中分離消息緩衝。即使沒有發佈匹配的接收,阻塞發送也可以在消息被緩衝後儘快完成。但是在某些情況下,消息緩衝可能很昂貴,因此直接從發送緩衝區複製到接收緩衝區可能是有效的。因此,MPI標準提供了四種不同的發送模式,爲用戶提供一些自由選擇適合其應用的發送模式。讓我們來看看在每個通信模式會發生什麼:
1標準模式
在標準模式,它是由該MPI庫,是否要緩衝傳出消息。在庫決定緩衝傳出消息的情況下,發送可以在調用匹配接收之前完成。在庫決定不緩衝的情況下(出於性能原因或由於無法獲得緩衝區空間),發送將不會返回,直到匹配的接收已發佈且發送緩衝區中的數據已移至接收緩衝區。
因此MPI_SEND在標準模式是,在標準模式下發送可以開始不論是否匹配接收已經公佈,其成功的完成可能取決於匹配的發生,收到感非本地(因事實上,如果消息將被緩衝,則它是實現相關的)。
標準發送的語法如下:
int MPI_Send(const void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
2.緩衝模式
像在標準模式中,在緩衝模式下的發送可以不考慮開始的事實,即一個匹配收到已發佈,發送可能會在匹配收到發佈之前完成。然而,主要區別在於如果發送被盯住並且沒有發送匹配的接收,則傳出的消息必須被緩衝()。請注意,如果發佈匹配的接收,緩衝的發送可以與開始接收的處理器愉快地集合,但是如果沒有接收,發送緩衝模式必須緩衝發出的消息以允許發送完成。整體而言,緩衝發送是本地。在這種情況下,緩衝區分配是用戶定義的,並且在緩衝區空間不足的情況下會發生錯誤。
語法緩衝器發送:
int MPI_Bsend(const void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
3.同步模式
在同步發送模式中,發送可以開始是否匹配的接收被張貼。但是,只有發佈匹配的接收並且接收方已經開始接收同步發送的消息,發送才能成功完成。同步發送的完成不僅表示發送中的緩衝區可以被重新使用,而且還表示接收過程已經開始接收數據。如果發送和接收都阻塞,那麼在通信處理器集合之前通信不會在任一端完成。
語法同步發送:
int MPI_Ssend(const void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm)
4.就緒模式
與前三個模式,在就緒模式的發送可以只有匹配的接收已經發布啓動。發送完成並不表示匹配接收的任何內容,只是表示發送緩衝區可以重新使用。使用就緒模式的發送與標準模式具有相同的語義,或者具有關於匹配接收的附加信息的同步模式。準備好通信模式的正確程序可以用同步發送或標準發送代替,而不影響性能差異對結果的影響。
語法準備發送:
int MPI_Rsend(const void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm)
幸運MPI決定讓事情easer爲用戶接受的條款和只有一個接收阻塞通信:MPI_RECV,並可以與任何使用上述四種發送模式中的一種。對於MPI_Recv,阻止裝置僅在其緩衝區中包含數據後才接收返回。這意味着接收只能在匹配發送開始後才能完成,但並不意味着匹配發送完成之前它是否可以完成。
在這種阻塞調用期間發生的情況是計算被暫停,直到被阻塞的緩衝區被釋放。這通常會導致計算資源的浪費,因爲Send/Recv通常將數據從一個內存位置複製到另一個內存位置,而cpu中的寄存器保持空閒狀態。
非阻塞通信: 對於非阻塞通信,該應用程序用於發送創建用於通信的請求和/或接收和回來的手柄,然後終止。這就是保證流程執行所需的全部內容。即通知MPI庫需要執行該操作。
對於發送方來說,這允許重疊計算和通信。
對於接收端來說,這允許重疊部分通信開銷,即將消息直接複製到應用程序中接收端的地址空間。
- 1. 非阻塞接收mpi + ocaml?
- 2. 在MPI中使用非阻塞發送和阻塞接收?
- 3. 如何修改MPI阻塞發送和接收到非阻塞
- 4. MPI將阻塞轉換爲非阻塞問題
- 5. 帶延遲的阻塞/非阻塞
- 6. 嵌套Socket阻塞非阻塞SocketHi
- 7. 非阻塞PASV襪子和阻塞
- 8. 是renderer.render()阻塞還是非阻塞?
- 9. 非阻塞寫入和阻塞recv
- 10. 非阻塞django?
- 11. 非阻塞setTimeout
- 12. 非阻塞spmd
- 13. 非阻塞pthread_join
- 14. PyGTK非阻塞
- 15. Javascript非阻塞
- 16. 非阻塞stdio
- 17. MPI:取消非阻塞發送
- 18. MPI非阻塞發送/ recv的
- 19. Fortran語言/ MPI非阻塞發送
- 20. MPI阻塞接收語義
- 21. MariaDB與EPOLL非阻塞
- 22. 非阻塞連接()與WinSocks
- 23. 異步與非阻塞
- 24. 阻塞或不阻塞(Express.js)
- 25. 使用select與阻塞和非阻塞套接字的影響
- 26. Linux阻塞與非阻塞串行讀取
- 27. 阻塞套接字性能與非阻塞套接字
- 28. 設備驅動程序DLL阻塞與非阻塞?
- 29. Python中的阻塞與非阻塞網絡IO
- 30. 非阻塞連接
所以MPI_Send()和MPI_Isend()+ MPI_Wait()是一樣的嗎? – lamba 2012-04-04 19:21:51
是的,除了開銷之外,您可以將MPI_Send()視爲MPI_Isend(),後跟MPI_Wait()。 – user1202136 2012-04-04 19:36:41
@ user1202136:您可能想提及,當您可以重新使用緩衝區時,「MPI_Send」會完成,而不管接收方是否已收到數據(或者甚至根本沒有發送數據)。 – 2012-04-04 22:54:55