MPI中如何發送C++對象?

如何使用MPI並行編程介面發送C++對象?找來找去網路上好像沒有詳細說明如何發送一個對象的文章,故來這裡求解。


MPI是消息傳遞介面,這裡面的消息基本上是指原始的位元組流。

而C++對象是一個挺複雜的東西,不光代表了一塊位元組,還和一些函數(也就是代碼)綁定在一起。

所以,一般沒有發送C++對象這種說法。你要先把對象轉化成位元組消息,然後發給另一個進程,然後另一個進程在這個消息的基礎上重建這個對象。這也費不了多少事兒呀。

mpi4py裡面好像就可以直接發送python對象,但是其內部也是轉成了位元組消息,然後接收方重建此對象。不知道有沒有現成的C++庫做這樣的事情然後封裝出一個好的介面,原始的MPI是不包括這功能的,它只認「消息」,雖然消息也可以有比較複雜的結構,但是我認為和C++的對象還是有點兒區別的。


艾瑪哥們你算問著了,我這幾天正搞這個呢,怒答一記。大體來說有三種方法,依序求決定:

1,自己把對象中需要發送/接收的元素放進一個數組中,接收之後再按照數組中的數據的順序重新建立一個對象。如果對象中只有int,bool的話,這個還比較好辦,double,string就麻煩一些。改變類的話就可能牽一髮而動全身。

2,自己定義一個結構體,把對象中需要傳輸的信息都複製進結構體中,然後MPI_Type_struct()定義一個數據類型,就可以直接用MPI收發了。不要忘了MPI_Type_commit()。

3,【推薦】使用Boost.MPI,方便快捷,不用考慮發送對象大小,數據類型等破事,快感翻倍。但是需要先對你的類進行serialize,就是在類裡面加一段函數。使用Boost的話,STL裡面的基本數據類型(一個由int組成的list或者vector)都可以直接發,由多個自定義對象組成的list的話,serialize之後也能直接發。

不過這都是上層方法,就如@藍木達 說的,根本上都是位元組流。


Boost.MPI+BoostSerialization.


你不能在運行時自動地干這件事,因為C++沒有反射能力,運行時不能知道一個類都有什麼成員。而且C++沒有簡單的內存模型。

你可以人工把它複製到一個struct里。或者把a list of structs變化成a struct of lists,比較便於發送。或者更乾脆的,不發送對象,只發送需要知道的信息。


用protobuf序列化是大家常用的一種方法。其實更直接的就是自己設計協議格式。

這些本質上都是C的思路,而不是C++,C++本來也不提供類的序列化。

其實MPI本來就是C庫。

最後是廣告時間(求不摺疊)。我們團隊在招人,雲計算、大數據、分散式計算人才很合適,歡迎投簡歷,具體信息參考 GeneDock 也歡迎推薦,成功入職後獎勵推薦人iPhone或DJI大疆無人機。


先用protobuf序列化成位元組數組。


Boost.Serialization

Boost庫是個很龐大的庫,功能非常豐富,序列化只是其中的一個小分支,但為了使用Boost的序列化方案,你需要安裝整個Boost庫,所花費的磁碟空間和時間都很多,同樣支持的序列化功能也很強大,既支持二維數組(指針),也支持STL容器,更不需要我們用某種特殊的格式重新定義我們的類結構,其非侵入的性質使得我們無須改動已有的類結構即可序列化,這時非常贊的一個性質。但是由於體積龐大,安裝複雜,如果只是簡單的序列化,沒必要使用該方案,只有protobuf不能滿足你的需求時,才應該考慮該方案。


推薦閱讀:

TAG:面向對象編程 | 並行編程 | 並行計算 | C | MPI |