10

我有一些研究相關的問題。這是什麼意思爲共享內存配置MPI?

目前我已經完成了基於MPI的結構骨架工作的實現(具體使用了openmpi 6.3)。框架工作應該在單機上使用。 現在,我與其他先前的框架實現它比較(如scandiumfast-flow,..)

有一兩件事我注意到的是,我實現的性能並不像其他實現一樣好。 我認爲這是因爲,我的實現基於MPI(因此需要匹配發送和接收操作的雙向通信),而我正在比較的其他實現基於共享內存。 (...但我仍然沒有很好的解釋來解釋這一點,這是我的問題的一部分)

這兩個類別的完成時間有一些很大的不同。

今天,我還介紹到這裏共享內存=>openmpi-sm

開放MPI的配置和有來我的問題是。

1st爲共享內存配置MPI意味着什麼?我的意思是,雖然MPI進程存在於自己的虛擬內存中,以下命令中的標誌究竟是幹什麼的? (我以爲在MPI中,每個通信都是通過顯式傳遞消息,進程之間沒有共享內存)。

shell$ mpirun --mca btl self,sm,tcp -np 16 ./a.out 

第二爲什麼MPI的性能相比,共享內存等開發框架實現與差這麼多?至少我也在一臺多核機器上運行它。 (我想這是因爲其他實現使用線程並行編程,但我沒有令人信服的解釋)。

任何建議或進一步的討論是非常受歡迎的。

請讓我知道,如果我必須進一步澄清我的問題。

謝謝你的時間!

回答

11

開放MPI是非常模塊化的。它有自己的組件模型,稱爲模塊化組件架構(MCA)。這是參數--mca的名稱的來源 - 它用於向MCA參數提供運行時值,由MCA中的不同組件導出。

只要給定通信器中的兩個進程想相互通信,MCA就會找到合適的組件,它們能夠將消息從一個進程傳輸到另一個進程。如果兩個進程駐留在同一個節點上,則Open MPI通常會選擇共享內存BTL組件,即sm。如果兩個進程駐留在不同的節點上,則Open MPI會遍歷可用的網絡接口,並選擇可連接到另一個節點的最快的網絡接口。它在InfiniBand(通過openib BTL組件)等快速網絡上放置了一些偏好,但如果您的羣集沒有InfiniBand,則在tcp BTL組件位於允許的BTL列表中時,將使用TCP/IP作爲後備。

默認情況下,不需要做任何特殊的事情來啓用共享內存通信。只需啓動您的程序mpiexec -np 16 ./a.out。你鏈接到的是Open MPI常見問題的共享內存部分,它提供了關於sm BTL的哪些參數可以調整以提高性能的提示。我的Open MPI經驗表明,默認參數幾乎是最優的,並且工作得很好,即使在像多級NUMA系統這樣的特殊硬件上也是如此。請注意,默認的共享內存通信實現將數據複製兩次 - 一次從發送緩衝區到共享內存,一次從共享內存到接收緩衝區。 KNEM內核設備的形式存在快捷方式,但您必須單獨下載並編譯它,因爲它不是標準Linux內核的一部分。通過KNEM支持,Open MPI能夠在同一節點上的進程之間執行「零拷貝」傳輸 - 拷貝由內核設備完成,它是從第一個進程的內存直接複製到第二個進程的內存處理。這極大地提高了駐留在同一節點上的進程之間的大消息傳輸。

另一種選擇是完全忘記MPI並直接使用共享內存。您可以使用POSIX內存管理接口(請參閱here)創建一個共享內存塊,讓所有進程直接對其進行操作。如果數據存儲在共享內存中,則可能是有益的,因爲不會創建副本。但要注意現代多插槽系統中的NUMA問題,其中每個插槽都有自己的內存控制器,並且從同一電路板上的遠程插槽訪問內存速度較慢。進程固定/綁定也很重要 - 通過--bind-to-socketmpiexec可將每個MPI進程固定到單獨的CPU內核。

+1

FWIW,從Linux 3.2開始,有一個process_vm_readv/writev系統調用,它與KNEM大致相同。見例如http://man7.org/linux/man-pages/man2/process_vm_readv.2.html – janneb

+0

@janneb,謝謝大家指出,但3.x內核在大多數生產HPC系統中都不是很受歡迎。然而KNEM提供的不僅僅是簡單的數據傳輸,例如異步操作,完成通知等。 –

+0

這是真的,但是再一次,KNEM補丁的內核也不例外。 – janneb