2013-07-10 28 views
1

鑑於以下情形,我有N個MPI進程,每個進程都有一個對象。當溝通階段到來時,來自這些對象的「通常很小」的數據將被交換。通常,任何兩個節點之間都有數據交換。在MPI進程之間交換數據(暈)

什麼是最好的策略?:

  • 在任何節點X,對於與此節點X的連接對方節點創建拖緩衝區,然後就發送/接收的對等網絡基礎。
  • 在每個節點X中,創建一個緩衝區來收集所有要傳送的暈數據。然後「bcast」該緩衝區。

  • 有沒有其他策略我不知道?

回答

11

對於最近鄰風格鹵素互換,通常最有效的實現方式中的一種是使用的MPI_Sendrecv呼叫的集合,通常是兩個每每個維度:

半步之一 - 正方向上的數據傳輸:每個秩從在其左側,並進入它的左滷代所述一個接收和發送數據到秩其右邊

+-+-+---------+-+-+  +-+-+---------+-+-+  +-+-+---------+-+-+ 
--> |R| | (i,j-1) |S| | --> |R| | (i,j) |S| | --> |R| | (i,j+1) |S| | --> 
    +-+-+---------+-+-+  +-+-+---------+-+-+  +-+-+---------+-+-+ 

S指定局部數據的一部分,而R名候被傳達到正被接收的數據的鹵素,(i,j)是秩的過程中網格座標)

半第二步 - 在負方向上的數據傳輸:每個秩從所述一個接收在其右側,並進入其右鹵素和將數據發送到的秩在其左側

+-+-+---------+-+-+  +-+-+---------+-+-+  +-+-+---------+-+-+ 
<-- |X|S| (i,j-1) | |R| <-- |X|S| (i,j) | |R| <-- |X|S| (i,j+1) | |R| <-- 
    +-+-+---------+-+-+  +-+-+---------+-+-+  +-+-+---------+-+-+ 

X是已經被填充在先前半步暈區的那部分)

大多數交換網絡支持多個同時的雙向(全雙工)通信和整個交換的等待時間是

上述兩個步驟的重複次數與域分解的維數一樣多。

該標準3.0版引入了所謂的鄰域集體通信,該過程更爲簡化。整個多維光環交換可以使用一次調用MPI_Neighbor_alltoallw來執行。

+0

謝謝@Hristo Iliev,不幸的是我必須使用MPI 2.不過,我將這種模式,一連串的級聯通信,也許我可以隱藏更多的通信背後的過程! – wonder

7

你在你的問題用字的建議,你可能會建立一個橫跨流程拆分計算域。這是MPI程序中廣泛應用的一種非常常見的方法。通常每個進程都在其本地域上進行計算,然後所有進程都會將halo元素與其鄰居進行交換,然後重複直至滿足。

雖然你可以創建專用緩衝區來交換halo元素,但我認爲更常用的方法,當然也是一種明智的第一種方法,就是將halo元素本身視爲你正在尋找的緩衝區。例如,如果您有一個跨100個進程的100x100計算域,每個進程都會得到一個12x12的本地域 - 在這裏我假設1個單元與4個正交鄰居中的每一個重疊,並注意全局域的邊緣。暈環單元在每個本地域的邊界處是那些單元,並且在通信之前不需要將這些單元編組到另一個緩衝器中。

如果我已經正確地猜出了您試圖執行的計算類型,您應該查看mpi_cart_create及其相關函數;這些設計旨在便於設置和實施計算步驟與相鄰流程之間的通信步驟交錯的程序。網絡充斥着創建和使用這樣的笛卡爾拓撲的例子。

如果這是您計劃的計算方式,那麼使用mpi_bcast絕對是錯誤的。 MPI廣播(和類似的功能)是集體所有進程(在給定的通信器中)參與的操作。廣播對於全球通信是有用的,但光環交換是本地通信。

+0

Thanks @High Performance Mark,我會嘗試mpi_cart_create和相關函數。 – wonder