高效能與平行計算

訊息傳遞(MPI)

/ MPI is said letter by letter, 'em-pee-eye' /

當工作者無法共用一張桌子——他們坐在沒有共同白板的不同建築裡——他們合作的唯一辦法就是互寄字條:「這是我的數」、「我需要你的」。訊息傳遞就是這種風格的平行程式設計,而 MPI(訊息傳遞介面)是幾乎每個大型科學模擬都用來做這件事的標準函式庫。它是計算如何鋪展到叢集或超級電腦那數千台各有私有記憶體的獨立電腦上的方式。

在 MPI 模型中,你一次啟動程式的許多份副本,稱為行程或 rank,編號 0、1、2 等等。每個 rank 跑相同的程式碼,但作用在自己那片資料上、在它無法共享的自己私有記憶體中。要交換資料,它們呼叫明確的運算:一個 rank 上的 send 配上另一個 rank 上的 receive,把一段數值緩衝區在兩者間搬動;集體運算則一次在整群間搬資料,例如廣播(rank 0 把一個值送給所有人)、散布(把各塊分給各 rank)、聚集(把各塊收回來),以及主力 reduce / allreduce(把每個 rank 的一個值合併——求和、取最大等——成單一結果)。典型的一步是:每個 rank 在自己的本地資料上計算,與鄰居交換邊界值,迴圈再重複。程式設計者要全權決定誰持有什麼、誰跟誰說話。

MPI 之所以重要,是因為它是大規模計算的通用語:它是程式碼觸及數十萬核心的方式,且該模型乾淨地對應到分散式記憶體硬體。但它的成本模型不留情面且明確。每則訊息有固定延遲(啟動它的時間,與大小無關)加上頻寬項(與其長度成正比),所以許多微小訊息遠比少數大訊息糟糕。通訊是純粹的開銷——資料在途中時沒有任何科學被算出——故 MPI 程式設計的藝術,是切分工作使每個 rank 有大量可算、很少且成批地通訊、並與同儕保持平衡。決定一個大型 MPI 程式能否擴展的,通常是通訊成本而非浮點運算數。

要在 1000 個 rank 間算一個全域內積,每個 rank 把自己的本地片相乘、加成一個部分數,接著單一次帶求和運算的 MPI_Allreduce 把全部 1000 個部分和合起來、把總和交回給每個 rank。總網路流量:約 1000 個數,在一次集體呼叫中——相對於若每個 rank 改成兩兩給其他每個 rank 發訊息的災難。

每個 rank 在本地計算,再由一次集體運算(allreduce)跨所有 rank 合併部分結果。

每則訊息都帶有固定的啟動延遲,所以一個發出許多小訊息的程式,即使酬載微小也可能被延遲主宰——把通訊綑成更少、更大的傳輸。而不匹配的 send 與 receive、或錯誤的訊息順序,會造成死結:各 rank 永遠互等對方。

又稱
MPImessage passing interface訊息傳遞介面MPI 介面