2012-07-17 36 views
1

我想使用異步通信加快我的MPI-程序。但使用時間保持不變。工作流程如下。MPI_Isend/Irecv:是否有可能同時訪問未使用的內存位置上的發送緩衝區

before: 
1. MPI_send/ MPI_recv Halo   (ca. 10 Seconds) 
2. process the whole Array   (ca. 12 Seconds) 

after: 
1. MPI_Isend/ MPI_Irecv Halo   (ca. 0,1 Seconds) 
2. process the Array (without Halo) (ca. 10 Seconds) 
3. MPI_Wait       (ca. 10 Seconds) (should be ca. 0 Seconds) 
4. process the Halo only    (ca. 2 Seconds) 

測量表明,Array-core的通信和處理對於常見的工作負載幾乎是相同的。所以不同步應該幾乎隱藏通信時間。 但它dosn't。

一個事實 - 我認爲這可能是問題 - 是sendbuffer也是計算的數組。儘管通信只訪問Halo(具有派生數據類型)並且計算只訪問數組的核心(只讀),但MPI是否可能序列化內存訪問?

有沒有人知道這是肯定的原因?

它可能是實現依賴(我正在使用OpenMPI)?

在此先感謝。

+0

如果消息足夠大以至於無法通過MPI實現進行內部緩衝,那麼後者將不會開始發送消息,直到接收方發佈匹配的接收爲止。你能發佈你的部分代碼嗎? – 2012-07-17 20:52:30

回答

0

MPI specification狀態:

甲非阻塞發送呼叫指示該系統可以開始複製 數據從發送緩衝區的。調用非阻塞發送操作後,發送方不應修改發送緩衝區的任何部分,直到 發送完成。

所以是的,你應該先將數據複製到專用的發送緩衝區。

+0

是的,但你可以讀*發送緩衝區,這可能是OP爲光環做的事情。 – 2012-07-17 19:23:16

+0

對!在通信正在運行時,我的計算只能從sendbuffer讀取,甚至不在相同的位置。 – user1466424 2012-07-17 19:31:06

1

並不是MPI將用戶代碼中的內存訪問序列化(這通常超出了庫的功能),確切發生的事情是實現特定的。

但實際上,MPI庫並沒有像你希望的那樣在後臺執行儘可能多的通信,而且在使用像tcp + ethernet這樣的傳輸和網絡時尤其如此,因爲在那裏沒有有意義的方法將通信傳遞給另一組硬件。

只有當您運行MPI庫代碼時,例如在MPI函數調用中,才能確定MPI庫實際上正在執行某些操作。通常,對任何一個MPI調用的調用都會推動實現「進度引擎」,以跟蹤機上消息並引導它們。因此,例如,您可以快速做的一件事就是對計算循環內的請求調用MPI_Test(),以確保事情在MPI_Wait()之前發生。這當然有開銷,但這是很容易測試的。

當然,您可以想象MPI庫會使用其他一些機制在幕後運行事情。 MPICH2和OpenMPI都使用與用戶代碼分開執行的單獨「進度線程」進行遊戲,並在後臺進行此操作;但如果要讓它運行良好,並且在嘗試運行計算時不佔用處理器,則是一個真正困難的問題。 OpenMPI的進度線程實現一直是實驗性的,事實上暫時不在當前(1.6.x)版本中,儘管工作仍在繼續。我不確定MPICH2的支持。

如果您正在使用infiniband,其中網絡硬件有很多智能,那麼前景會變得更加明亮。如果你願意讓內存固定(對於openfabrics),並且/或者你可以使用特定於供應商的模塊(mxm用於Mellanox,psm用於Qlogic),那麼事情可以更快一些。如果你使用共享內存,那麼knem kernel module也可以幫助intranode傳輸。

如果內存不是一個大問題,您可以採取的另一種實現特定方法是嘗試使用eager protocols直接發送數據,或者每個塊發送更多數據,因此需要更少的進度引擎微調。這些熱切的協議意味着數據在發送時自動發送,而不是僅僅發起一組握手,最終導致消息被髮送。壞消息是,這通常需要額外的緩衝存儲器,但如果這不是問題,並且您知道傳入消息的數量是有限的(例如,通過您擁有的暈圈鄰居的數量),這可以幫助大量處理。在the OpenMPI page for tuning for shared memory上描述瞭如何爲(例如)openmpi的共享內存傳輸執行此操作,但其他傳輸通常存在類似的參數,並且通常用於其他實現。 IntelMPI的一個很好的工具是一個「mpitune」工具,它可以自動運行多個這樣的參數以獲得最佳性能。

相關問題