MPI(Message Passing Interface)

【應該瞭解的背景知識】
1、MPI知識--[比較熟悉]
2、VC/Visual Studio知識--[一般瞭解]
3、C++知識--[熟悉]

 

 

MPI全稱消息傳遞接口,是Message Passing Interface的縮寫,MPI是一個庫,而不是一門語言。它是一種標準或規範的代表,而不特指某一個對它的具體實現。

本次實驗過程中,使用的MPI實現是MPICHMPICH是一種最重要的MPI實現,它可以免費從http://www-unix.mcs.anl.gov/mpi/mpich 取得,更爲重要的是,MPICH是一個與MPI-1規範同步發展的版本,每當MPI推出新的版本,就會有相應的MPICH的實現版本。

MPICH的下載安裝

       可以從http://www-unix.mcs.anl.gov/mpi/mpich 免費下載得到MPICH的最新版本。本次實驗使用的是MPICH2 for Microsoft Windows 版本是1.0.3 ,下載後直接運行,安裝即可。

MPICH的配置

       本次實驗使用的開發語言是C/C++,運行環境爲Microsoft Windows XP Professional,開發工具爲Microsoft Visual Studio 2005。安裝完MPICH2後,要將MPI庫添加到Visual Studio的庫目錄中,將inculde文件添加到Visual Studioinclude目錄中。具體步驟如下:

1.     單擊“工具”菜單,選擇“選項”,在彈出對話框中雙擊樹型目錄中的“項目和解決方案”,打開之。在其子目錄裏面選中“VC++目錄”一項,此時右側顯示相應屬性。

2.     在“顯示以下內容的目錄”下拉菜單中選擇“庫目錄”,單擊“新行”按鈕(快捷鍵Ctrl+Insert),在新添加的行中單擊最右側瀏覽按鈕,選擇MPICH2的安裝目錄,然後選擇lib子目錄,選擇“打開”,加入完成,如圖:

3.     使用與第二步相同的方法,將“引用文件”添加上,如圖:

4.     新建一個空白“Windows控制檯應用程序項目,假設命名爲FFT,在“項目”菜單中選擇“FFT屬性”,在彈出對話框中依次開左側樹型列表的“配置屬性”、“鏈接器”、“輸入”,在“附加依賴項”一欄輸入:mpi.lib,如圖:

選擇配置下拉列表中的release選項,同樣將mpi.lib添加上去。(也可以使用#pragma預處理指令:#pragma comment(lib,"mpi.lib")

 

程序運行與測試:

       VC下將程序直接編譯鏈接爲exe文件,然後使用MPICH2附帶的運行工具即可模擬運行並行程序。

       在運行程序前,要對MPICH2的運行環境進行設置,本次實驗僅使用一臺計算機來進行模擬,所以,設置比較簡單,使用開發包提供的wmpiregister即可。如果要同時使用多太計算機來運行,就要用到wmpiconfig工具來進行配置。兩個工具都位於mpi安裝目錄下的bin目錄中。這裏,我們只介紹wmpiregisterwmpiregister運行界面如下:

      

程序的設置很簡單,只要在Account中輸入你當前登錄Windows所使用的用戶名,在password中輸入該用戶名對應的密碼即可。MPICH2不能使用沒有密碼的用戶,如果當前用戶沒有密碼,則應該爲其創建一個,然後再運行wmpiregister進行配置。輸入完成後,單擊Register進行註冊即可。顯示Password encrypted into the Registry,即表示註冊成功。

MPICH2帶有兩個運行工具,第一個爲mpiexec.exe,第二個爲wmpiexec.exe,均位於mpi安裝目錄下的bin目錄中。第一個爲命令行工具,使用方法如下:

2個參數爲處理器個數,第4個參數爲將要運行的程序。

       第二個爲Win32窗口程序,運行後界面如下:

其實這個程序僅僅是一個界面,最終程序仍然要調用mpiexec.exe來運行,所以兩種方式本質上是相同的。這裏更建議使用命令行方式,或在使用窗口方式時將“run in a separate window”勾中,因爲經過多次實驗,發現窗口方式運行時,輸出顯示是沒有問題的,但是如果要向程序輸入數據,在窗口模式下似乎行不通,估計mpiexec這個程序有問題。

 

 

MPI(Message Passing Interface)是消息傳遞並行程序設計的標準之一,當前通用的是MPI1.1規範。正在制定的MPI2.0規範除支持消息傳遞外,還支持MPI的I/O規範和進程管理規範。MPI正成爲並行程序設計事實上的工業標準。

  MPI的實現包括MPICH、LAM、IBM MPL等多個版本,最常用和穩定的是MPICH,曙光天潮系列的MPI以MPICH爲基礎進行了定製和優化。

  MPICH含三層結構,最上層是MPI的API,基本是點到點通信,和在點到點通信基礎上構造的集羣通信(Collective Communication);中間層是ADI層(Abstract Device Interface),其中device可以簡單地理解爲某一種底層通信庫,ADI就是對各種不同的底層通信庫的不同接口的統一標準;底層是具體的底層通信庫,例如工作站機羣上的p4通信庫、曙光1000上的NX庫、曙光3000上的BCL通信庫等。

  MPICH的1.0.12版本以下都採用第一代ADI接口的實現方法,利用底層device提供的通信原語和有關服務函數實現所有的ADI接口,可以直接實現,也可以依靠一定的模板間接實現。自1.0.13版本開始,MPICH採用第二代ADI接口。

  我們將MPICH移植到曙光3000高效通信庫BCL(Basic Communication Library)上(簡稱MPI_BCL)。MPI_BCL的接口標準與MPICH版本1.1完全一致,滿足MPI1.1標準。同時,也支持ch_p4的通信庫,即利用TCP/IP通信機制。從網絡硬件角度說,MPI_BCL針對系統網絡,MPI_ch_p4針對高速以太網。

1.MPI的程序設計

  MPI1.1標準基於靜態加載,即所有進程在加載完以後就全部確定,直至整個程序結束才終止,在程序運行期間沒有進程的創建和結束。一個MPI程序的所有進程形成一個缺省的組,這個組被MPI預先規定的Communicator MPI_COMM_WORLD所確定。

  MPI環境的初始化和結束流程如下:在調用MPI例程之前,各個進程都應該執行MPI_INIT,接着調用MPI_COMM_SIZE獲取缺省組(group)的大小,調用MPI_COMM_RANK獲取調用進程在缺省組中的邏輯編號(從0開始)。然後,進程可以根據需要,向其它節點發送消息或接收其它節點的消息,經常調用的函數是MPI_SEND和MPI_RECV。最後,當不需要調用任何MPI例程後,調用MPI_FINALIZE消除MPI環境,進程此時可以結束,也可以繼續執行與MPI無關的語句。

  上面提到的六個函數:MPI_INIT,MPI_COMM_SIZE,MPI_COMM_RANK,MPI_SEND,MPI_RECV,MPI_FINALIZE 實際上構成了編寫一個完整的MPI程序所需例程的最小集。

2.MPI的幾個重要特徵

  下面分別介紹MPI的幾個重要特徵:Communicator(通信空間)、Group(進程組)、Context_id(上下文標識)、Data Types(數據類型)。
MPI提供Communicator來指定通信操作的上下文,提供了通信操作的執行空間。在某個通信空間(或上下文)中發送的消息必須在相同的空間中接收,不同空間中的消息互不干擾。定義一個Communicator,也就指定了一組共享該空間的進程,這些進程組成了該Communicator的Group。

  Communicator通過其特徵屬性Context_id來區分,同一個進程不同的Communicator有不同的Context_id。因此Context_id是另一個區分消息的標誌。

  MPI引入消息的Data Type屬性的目的有兩個:一是支持異構系統計算;二是允許消息來自不連續的或類型不一致的存儲區,例如,可以傳送數組的一列,或傳送一個結構值,而該結構的每個元素的類型不同。Data Types定義了消息中不連續的數據項及其可能不同的數據類型。Data Type由應用程序在執行時通過基本的數據類型創建。

3.消息

  一個消息相當於一封信,消息內容相當於信本身,消息的接收者相當於信封上的內容。因此通常將前者稱爲消息的buffer, 後者稱爲消息的envelop。

  buffer: message address, count, datatype;
  envelop: process id, message tag,communicator

  在MPI以前的大多數通信系統中,消息buffer通常僅由buffer的地址和長度決定(例如曙光1000上的NX通信系統),那麼在MPI的消息格式中爲什麼要引入Data Type呢?這有兩個主要原因:

  支持異構計算:不同系統有不同的數據表示。解決這一問題的方法是預先定義一些基本數據類型,MPI實現過程中對這些類型進行轉換,例如轉換爲XDR格式,接收時進行反轉。

  派生的數據類型(Derived Data Types):允許消息來自於不連續的和類型不一致的存儲區域。

4.MPI應用程序的編譯

Include文件

  C語言應用程序應有
    #include "mpi.h"
  若使用cc編譯,命令行應有:
    -I/cluster/mpi/net/include (net版)
    -I/cluster/bcl/include -I/cluster/rms/include -I/cluster/sdr/include -I/cluster/mpi/mesh/include (mesh版)

  Fortran語言應用程序應有
   include 'mpif.h'
  若使用f77編譯, 命令行應有:
    -I/cluster/mpi/net/include (net版)
    -I/cluster/bcl/include -I/cluster/rms/include -I/cluster/sdr/include -I/cluster/mpi/mesh/include (mesh版)

MPI庫文件

C語言
  C語言程序編譯時需作下述鏈接:
    -L/cluster/mpi/net/lib -lmpi -lbsd (net版)
    -L/cluster/mpi/mesh/lib -L/cluster/bcl/lib -L/cluster/rms/lib -L/cluster/sdr/lib -lmpi -lbcl -lrms -lsdr (mesh版)
  數學函數庫還應鏈接: -lm

Fortran語言
  Fortran編譯時應作下述鏈接:
    -L/cluster/mpi/net/lib -lmpi -lbsd (net版)
    -L/cluster/mpi/mesh/lib -L/cluster/bcl/lib -L/cluster/rms/lib -L/cluster/sdr/lib -lmpi -lbcl -lrms -lsdr (mesh版)

mpif77和mpicc

  MPI提供了兩個工具(mpif77和mpicc)來簡化MPI應用程序的編譯。用戶可以直接地使用命令行方式mpicc或mpif77來編譯C或Fortran程序,編譯方式與cc和f77完全一致。如:
    mpif77 -c foo.f
    mpicc -c foo.c
    mpif77 -o foo foo.o
    mpicc -o foo foo.o
  有時鏈接時需一些特殊庫, 應在鏈接時註明。使用mpicc和mpif77省略了有關MPI的路徑設置。

5.MPI應用程序的運行

  應用程序編譯好後,使用mpirun命令運行MPI應用程序。mpirun命令完整的格式如下:
    mpirun [-h|-?|-help] [-sz size|-sz hXw] [-np nprocs] [-pl poolname]
  各個選項的值由用戶從命令行中顯示地指定,選項的含義如下:
  -h
  -?
  -help:顯示幫助信息。

  -sz
  指定物理節點的數目。有兩種指定形式,一是直接指定size值,另一種是指定物理節點的矩形域的長和寬。size值和h*w的值如果超過所在pool的節點數,sz項的值取pool的節點數,h*w值取整個pool。兩者的缺省值分別爲所在pool的節點數和整個pool。

  -np
  用戶期望運行的進程數。進程數與實際申請的物理節點數沒有任何聯繫,因爲允許一個節點上運行同一個應用的多個進程。如果未指定,取實際sz項的值。

  -pl poolname
  應用程序執行的pool。應用程序的每次執行能且只能在一個pool中執行。缺省值爲系統爲用戶設置的缺省的pool名(每個用戶在創建時已自行指定或系統分配了一個缺省的pool)。

  在運行選項後,是用戶的程序名。該可執行文件必須在所指定的或缺省的pool中的所有節點上能找到,並且與啓動節點上的路徑一致。用戶程序名後的一切字符串都視爲其參數(不包括被shell解釋的重定向等,對shell解釋的一些特殊字符,如需作爲參數,應作相應的轉換)。因此運行選項與用戶程序名有先後的順序,先運行選項,後用戶程序名和參數。

發佈了144 篇原創文章 · 獲贊 6 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章