趙 晨,張淑萍
(中國航天科工集團第二研究院706所,北京 100854)
為解決單核計算機運算能力有限,無法適應現今信息膨脹、運算需求急劇增長的環境,多核/眾核計算模式、集群系統等新型計算體系應運而生,針對集群系統所設計開發的標準接口與通信協議也層出不窮,如基于共享存儲的OpenMP、Pthread和基于消息傳遞的MPI、PVM等。本文研究的MPICH2是一種基于集群并行計算通信標準接口MPI(message passing interface)的具體實現。第二代消息傳遞接口實現(MPICH2)默認采用TCP/IP協議進行節點間通信,集群間通過消息傳遞進行數據互通且信息傳遞模式適用于多重設定,獨立于網絡速度和內存架構中,具有高度的可移植性,逐漸成為廣泛使用的集群并行運算接口[1]。
現今出現的若干網絡通信協議及硬件通信平臺,針對集群間通信頻繁的特點做出相應優化,對于連接建立/拆除、數據流阻塞/非阻塞等具體問題提供更為實用的方式,極大降低了網絡的通信延遲,提升網絡通信性能,這些提升單單通過傳統的TCP/IP協議顯然不足。現今一些人已針對如何提升MPICH2集群通信性能進行相關研究,Ren′e Grabner等[2]提出使用InfiniBand高速互聯網絡構建MPICH2的數據分發接送這樣一種研究思路;Cray公司的Howard Pritchard等[3]提出基于MPICH2底層Nemesis通道進行拓展,加入一種用戶層通用網絡接口用于支持其公司自有的CrayXE超級計算機;金亨科等[4]使用RapidIO替代傳統的設備層,采用RapidIO底層硬件以及接口,為脫離采用以太網模擬器使用RapidIO這一劣勢,借鑒SCTP協議開發出SRI接口實現MPI上下層之間的通信并實驗驗證。然而這些研究建立在特定的硬件實現平臺上,移植性有限,少有建立MPI上層應用與底層設備實現之間的統一接口,為不同硬件通訊平臺的相互移植帶來困難。
為實現節點間通信效率的提升以及構建更加開放的平臺環境,本文采用一種透明進程間通信協議TIPC(transparent inter-process communication),代替MPICH2默認采用的TCP/IP協議進行節點間通信。本文通過實驗對比TCP/IP協議與TIPC協議在連接頻繁建立/拆除過程中的性能差異,隨后分析MPICH2源碼架構,借鑒TCP/IP在MPICH2中的實現方式及分段傳輸的設計思路,利用TIPC網絡拓撲追蹤及傳輸流控特點,設計出基于MPICH2的CH3通道下適合于TIPC協議的通信通道,完成向CH3通道下植入TIPC協議的過程,最后通過運行實際的測試程序,驗證拓展后的MPICH2在節點間通信上具有更小的延遲和更高的傳輸帶寬。
TIPC由愛立信公司Maloy J等開發,目前由風河公司維護[5]。Linux 2.6.30及以上版本中已將TIPC內核模塊作為可加載項植入內核中。其實現結構如圖1所示。

圖1 TIPC結構框架
TIPC最上層實現了與用戶間建立連接交互的各項接口,包括通用的socket接口、TIPC自定義的Port接口以及用戶自行編寫的其它接口;中間層為TIPC的內核組態,包含與通信接口建立連接的各項通信端口,以及地址服務、名稱管理服務等核心的實現;最下層包含通信的物理層和鏈路層,對于TIPC基礎包而言支持以太網、共享內存以及分布式共享內存3種鏈路形式,后續開發人員針對底層通信拓展了TIPC的傳輸模式,包括RapidIO、PCIe等,從理論上將,TIPC支持幾乎所有底層通訊設備[6]。TIPC專門針對機群通信開發,具有通過功能性地址完全透明、快速可靠的進程間通信及動態感知節點增加/刪除三大特征。
TCP/IP協議有其強大的普適性和眾多優點,被絕大多數程序員和用戶所熟知,但功能性地址不透明、建立/拆除連接過程繁瑣的客觀問題的存在使其在集群通信的條件下表現不佳,而TIPC協議在集群通信頻繁的條件下則更具優勢。Stylianos Bounanos等[7]與冀映輝等[8]分別在其文章中闡述了兩者的對比實驗,均驗證這一結論。
筆者在兩臺裝有千兆網卡的主機上進行乒乓傳輸收發測試,實驗TCP/IP協議與TIPC協議傳輸時間上的差異。通信時間按照客戶端首次發起連接請求開始到最后一次接收到回復數據后斷開連接為止。套接字緩沖區按照協議默認值設置,連續通信次數總計為100 000次。得到的測試結果如圖2所示。

圖2 ping-pong實驗結果
在傳輸數據大小相同的情況下,TIPC傳輸的時間要小于TCP/IP協議,平均減小了約20%,網絡吞吐量高于TCP協議,提升了約25%左右,驗證了TIPC在建立/拆除連接過程中的優勢,值得一提的是,隨著發送數據量的增加,TIPC協議會比TCP協議更快的達到網絡吞吐量的峰值。由于系統網絡端口recv()每次最多接收4244 Byte數據,且多于4 k數據在機群通信中少有一次性發送,故僅測試4 k及以下數據。由于TIPC允許一次最多發送的緩沖區大小不大于66 000字節,TCP/IP為65 536字節,所以以上數據發送均在一次數據拷貝中由應用拷貝到內核態然后進行發送,所以產生的發送延時主要取決于連接建立和拆除中造成的時延[9]。
MPICH2是一款高性能,廣泛實現MPI-1與MPI-2所定義的標準接口的應用實現,其支持多平臺的最主要原因就在于源碼的層次性鮮明,可在不修改上層源碼的基礎上,重新編寫底層設備支持,完成應用實現的移植。MPICH2具有典型的3層結構[10],最上層MPICH2實現了用戶編程應用使用的全部接口,包括MPI的初始化、主/從機之間的消息發送與接收等,絕大多數接口都包含在mpi.h頭文件中,方便使用者直接調用而無須關注其下層的具體實現;ADI層(abstract device interface)是整個體系架構中最核心的部分,抽象了下層設備提供的具體接口,所有的MPI實現都建立在ADI層與其上下層協調配合中;ADI層往下為CH3層(channel interface),各種通信傳輸協議與實現就位于該底層結構中。CH3層作為最底層通道,包含多種底層設備的實現與抽象,可以便捷地進行平臺的移植。CH3層提供多種傳輸通道,包括Nemesis、SCTP等,默認通過Nemesis通道進行網絡通信,而我們所關注的TCP協議就位于Nemesis通道下。作為一款并行處理接口的應用實現,MPICH2具有相應的管理與監測工具如MPD和MPE,在此不一一贅述。
2.2.1 整體思路
在MPICH2-1.0.5p4版本源碼中,CH3層共提供5種底層通道進行數據傳輸,分別為TCP傳輸協議sock、sctp、nemesis、shm、以及ssm。在MPI執行初始化進程過程,調用MPI_Init()函數時,依照當前默認配置的網絡模式配置傳輸模式,調用相應的CH3底層代碼。5種傳輸通道最上層源碼提供相同的接口供ADI層配置調用,針對不同配置調用不同封裝包內的函數。我們在CH3通道下修改sock通道模式,在此處添加TIPC連接的相關庫文件與源碼文件,同時需要重寫MPICH2下TCP協議進行數據收發操作的相關函數,如有request對象需求的MPIDI_CH3_iSend(發送數據包頭)和MPIDI_CH3_iSendv(數據包頭+數據消息體),及無request對象需求的MPIDI_CH3_iStartMsg(發送數據包頭)和MPIDI_CH3_iStartMsgv(數據包頭+數據消息體)等。
由于TIPC協議規定的連接地址與傳統TCP協議有所區別,我們規定在CH3接口建立連接的過程中,首先進行連接地址轉換操作,將MPI定義的進程號轉化為TIPC協議傳輸需求的端口名稱。隨后,調用ch3_init.c下的MPIDI_CH3_Init()函數,初始化通信端口,向進程組注冊連接信息以及初始化套接字等操作,建立與目的地址端口的相互連接。在進行一次數據收發的過程中,上層函數將發送函數提供的發送緩沖區以及目的地址進行初步處理,將相關信息傳遞到CH3接口中,依照發送目的地址以及數據長度分配不同的發送函數。對于消息緩沖區的處理,將發送隊列數據頭指針*buf和數據長度data_sz存放于數據聚散發送I/O結構iovec中向下傳遞,等待底層TIPC調用tipc_send()等API定義函數發送到指定端口名稱處,完成一次數據發送。數據接收隊列不做特殊處理,與MPICH2所定義接收方式相同。
2.2.2 連接地址轉換
為使集群系統運行像一臺主機般運行,在通信過程中隱藏各節點的物理地址,采用功能性地址通信是目前通用的通信策略。MPICH2在上層通過進程號指明通信語句的交互對象,例如API中描述:
int MPI_Send(void *buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)。dest表明目的進程所在的節點,ADI層將該進程號存入虛鏈接VC(virtual connection),在虛鏈接中建立進程號與通信地址的key-value 鍵值對,同時將要傳遞的buffer寫入到IOV中,這樣,在CH3層進行sock通信的過程中,通過查找對應的key-value鍵值對,即可準確定位接收端,完成消息傳遞。
TIPC采用端口名稱服務進行無連接或面向連接的數據傳輸,每個節點的通信單元都有一個獨特的端口名稱,通信單元將套接字綁定到端口名稱上,在與其它設備建立連接的過程中,TIPC底層將端口名稱進行翻譯,與下層物理地址建立對應,保證數據正確的傳輸到對應的套接字節點上。端口名稱結構tipc_name包含兩個32位信息,如下所示:
struct tipc_name {
__u32 type;
__u32 instance;
};
type表示端口的服務類型,instance表示服務類型的具體實例,兩者結合成為一個端口對外溝通的唯一渠道。tipc_name結構存儲于sockaddr_tipc套接字地址結構中。為將TIPC植入MPICH2中作為通信通道,有必要在CH3層建立連接地址的轉換,將進程號轉變為tipc_name。為此,在mpidpre.h頭文件下建立MPIDI_VC_TIPC結構如下:
typedef struct MPIDI_VC_TIPC
{
int handle;
volatile int ref_count; /* 使用同連接的通信子個數 */
MPIDI_VC_State_t state; /* VC當前通信狀態*/
MPIDI_PG_t * pg; /* VC所屬進程組 */
int pg_rank; /* 進程組對應的標識 */
int lpid; /* Local process ID */
struct sockaddr_tipc sockaddrtipc; /* TIPC端口名稱域 */
# if defined(MPIDI_CH3_VC_DECL)
MPIDI_CH3_VC_DECL /* VC當前狀態及Socket */
# endif
};
在CH3層對VC進行處理時,提取VC結構包含的進程號rank賦予到變量NODE_INST中。點對點通信中,默認TYPE變量為固定值18888,定義函數MPID_Comm_TIPC_get_name(),將NODE_INST中保存的進程號賦予VC結構sockaddrtipc.addr.name.name.instance中,等待CH3層調用相關通信函數時使用。
2.2.3 連接建立拆除方式
機群服務器將計算量分配到不同的機群節點中實現并行計算,再將最終結果匯總到服務器端完成一次機群計算調度,在運算時間上遠遠小于單核計算機運算時長。在這個過程中,根據計算任務本身以及服務器任務調度的不同,機群各節點間可能存在頻繁的通信和數據交換需求,而這一部分時間在整體任務完成時長中所占的比重無法忽視。設機群系統完成一次計算任務,即整個應用程序的運行時間為Ttotal,理想狀態下,程序運行時間包括計算時長Tcpt與通信時長Tcmn兩部分組成,并且彼此之間沒有重疊。則存在Ttotal=Tcpt+Tcmn。其中,Tcpt依據具體計算任務的不同需具體分析,假設機群節點間一次建立、拆除的時間為Tb&d,每次消息傳遞的長度固定為Lm且與傳遞時長Tsd成正比k(k為常數),消息共發送N次,則有Ttotal=Tcpt+N×(Tb&d+kLm) 由此看出,理想情況下,通信時長主要取決于通信連接的建立、發送/接受的時長這兩方面因素。在MPICH2默認的SOCK通信模式下,使用PF_INET協議族綁定流套接字SOCK_STREAM,執行標準TCP握手流程,該模式面向連接,提供可靠傳輸,而其缺陷也在于此。過于冗雜的連接開銷巨大,致使完成一次通信所需時長較長,不利于并行計算效率進一步提升。為優化該傳輸過程,現使用TIPC流式傳輸模式作為CH3層通信通道傳輸方式,簡化通信連接建立/拆除步驟。
如圖3所示,連接建立過程中,Client端引用create()函數創建一個通信端口cport并向服務器端發送一份攜帶NAMED_MSG信息的有效數據載荷(4),Server端初始端口suport接收該有效數據,閱讀其中內容以識別發起請求的cport端口。隨后,Server端創建一個新端口sport(5)并發起到Client端的連接請求lconnect()(6),此時,lconnect()調用是一個本地操作,直到Server端滿足連接請求并向Client端回復一份攜帶CONN_MSG信息的數據載荷(7),在接收到響應消息后,客戶端讀取服務器端口信息并對其執行lconnect()(8),雙方的連接正式建立。通過這種方式,雙方在無需發送協議標志位信息的情況下即可建立相互連接。

圖3 TIPC連接建立
連接拆除的過程相較建立情況更為簡單,如圖4所示,Client端調用close()(1)功能,同時刪除Client端端口信息。刪除連接的端口具有以下效果:具有錯誤代碼NO_REMOTE_PORT的DATA_NON_REJECTABLE/CONN_MSG(在TCP術語中為“FIN”)被發送到另一端。接收到這樣的消息意味著接收側的TIPC必須關閉連接,并且這必須在通知Server端之前完成。然后Server端必須調用close()(2),不要關閉連接,而是要刪除端口。由于Client端口已經關閉通信端口,TIPC本次不發送任何“FIN”。完成此項操作后,雙方連接拆除,表明一次通信完成。

圖4 TIPC連接拆除
2.2.4 傳輸過程設計及流量控制
TIPC支持采取流式傳輸進行數據傳遞,對此可設定MPICH2節點間基于流式傳輸的分段思想。雖然這種方式仍屬于面向連接類型但不同于傳統TCP/IP面向連接的流式傳輸。以雙節點Client端與Server端建立通信傳輸為例,雙方定義傳輸類型為AF_TIPC協議族中SOCK_STREAM套接字類型并將其綁定到對應套接字結構sockaddr_tipc中,客戶端進行完綁定套接字地址等一系列操作后,依照所要發送數據大小進行分段打包處理,設定一次包傳輸大小上限MSG _SIZE,超出此段上限的數據控制在下一數據包中。每段數據包頭部加入4字節該段長度描述rec_size保證數據傳輸完整性。分段打包完成后數據結構如圖5所示。
打包完成后,將數據包依次存入預先設定的iovec結構,同時,從虛連接結構VC中提取發送目的進程端口dest_port相關數據,通過tipc_send()函數將發送數據拷貝到發送緩沖區等待協議發送,每次發送數據上限為常量MSG_SIZE(最后一次發送數據大小為tot_size-sent_size)。部分實現代碼如下:
…
sent_size=0;
while (sent_size if ((sent_size + MSG_SIZE) <= tot_size) msg_size = MSG_SIZE; else msg_size = (tot_size-sent_size); my_iov.iov_base =&(sendbuf+sent_size);/* 存儲發送緩沖區指針到iovec */ my_iov.iov_len =msg_size + 1;/* 存儲發送數據大小到iovec */ if (0 > tipc_send(dest_port,1,&my_iov)) { perror("Client:failed to send"); exit(1); } sent_size += msg_size;/* 使用同連接的通信子個數 */ } … 接收端在接收到數據包后,依照數據包頭指定的數據大小進行解包操作,將數據還原。值得一提的是,TIPC在下層源碼中實現數據校驗及確認/重傳機制,編程者在上層應用中無需考慮。 圖5 數據分片發送 本實驗建立在兩臺裝有千兆網卡網絡互聯的節點主機進行數據收發測試,測試環境為主機節點CPU:i5-460M-2.54GHz,內存4G;從機節點:CPU:i7-6700HQ-2.6GHz,內存8G。程序運行在Linux 4.4.0-2-deepin-amd64內核版本下,使用俄亥俄州立大學(OSU)公布的MPI基準測試程序進行相關測試,兩個節點在一次通信中,分別向對方發送一份固定消息窗大小的消息,然后同時等待接收方回復確認信息,實際操作中,通過定義兩類不同的發送進程號標志位tag對應通信通道,避免造成數據混亂或鏈路死鎖等問題。發送接收函數采用無阻塞發送接收方式MPI_ISend與MPI_IRecv。多次重復該項進程后通過傳輸流程時間總長(從發送方第一次發送數據到發送方最后一次接收確認信息為止)以及消息傳輸總字節數來計算帶寬。測定所得單雙邊通信帶寬結果如圖6、圖7所示。 圖6 單邊通信帶寬 圖7 雙邊通信帶寬 基于TIPC協議的MPICH2并行程序接口在傳輸帶寬上表現出良好的上升特性,整體帶寬提升效率在10%~20%左右。相比之下,傳統MPICH2通信帶寬上升遲緩。由于TIPC協議在小數據量情況下,無需單次發送確認重傳等相關信息位數據,在底層盡量減少除發送數據外的其余操作,故通信帶寬上升較快,大約在1 k左右到達傳輸峰值的90%。為得益于TIPC協議下層本身針對快速頻繁的數據通信采取的流式傳輸方式以及簡潔的流量控制處理,TIPC協議在整體傳輸帶寬上優于傳統TCP協議,在大數據量情況下,由于采用分片發送機制,仍可以保持較高的通信帶寬。測試結果與預計理論值有一定差距,主要原因在于兩臺節點處于網絡直連狀態進行點對點傳輸,傳輸瓶頸除默認預配置網絡連接速度外,還受限與兩臺節點各自硬盤拷貝速率和處理能力等因素。 同樣采用OSU標準測試程序測定單雙邊集群通信延遲。類似乒乓傳輸機制,發送方向接收方發送一份確定消息長度的數據同時等待接收方反饋一份接收確認,接收方在接受到消息后向發送方回復相同長度大小的數據并等待發送方回復接收確認連續不斷重復過程并求取單邊延遲平均值。該程序采用阻塞發送函數MPI_Send與MPI_Recv進行數據傳輸。測試結果如圖8、圖9所示。 圖8 單邊通信延遲 圖9 雙邊通信延遲 可以看出,經由TIPC協議進行傳輸的MPICH2通信函數在數據發送接收時間延遲上與原MPICH2函數相比,在小數據量情況下下降約50%,在1 k數據點以后通信延遲下降整體維持在20%左右。符合TIPC針對集群通信小數據量特點制定的傳輸優化策略。在小數據量傳輸時,TIPC面向連接傳輸在下層實現傳輸的完整性驗證,乒乓實驗中針對發送的數據量采用批量驗證模式,極大減小了傳統TCP協議每次調用發送接收函數后均需進行的數據確認驗證(SYN+ACK),故在小數據量發送接收階段通信延遲急劇下降。在數據量逐漸增大階段,由于網絡帶寬以及由硬盤拷貝速度帶來的傳輸瓶頸,通信延遲下降程度與小數據量階段相比有所下降,符合傳輸特性。 本文將針對集群通信所設計的透明進程間通信協議TIPC運用到并行計算實現接口MPICH2中,替代MPICH2默認采用的TCP傳輸協議,利用TIPC面向連接的流式傳輸模式進行數據傳輸過程,簡化數據傳輸過程。該技術目前可應用與基于以太網連接的Linux集群系統做并行計算處理。由于TIPC協議在理論上支持絕大多數底層連接方式,例如共享內存、RapidIO、PCIe等,未來可在CH3的TIPC通道下添加下層對于各種底層設備的描述,即可實現相應的集群通信,以及TIPC支持的多路冗余可靠性傳輸以及傳輸優先級判別等功能。 [1]LU Yun’e,HUANG Zongyu,LI Chaoyang,et al.The MPI parallel computing based on the microcomputer cluster[J].Electronic Design Engineering,2011,19(5):78-81(in Chinese).[盧云娥,黃宗宇,李超陽,等.基于微機集群系統的MPI并行計算[J].電子設計工程,2011,19(5):78-81.] [2]Grabner R,Mietke F,Rehm W.An MPICH2 channel device implementation over VAPI on infiniBand[J].Proceedings-International Parallel and Distributed Processing Symposium,2004,18:2581-2588. [3]Pritchard H,Gorodetsky I.A uGNI-Based MPICH2 nemesis network module for Cray XE computer systems[G].LNCS 6960:Computer Science,2011:110-119. [4]JIN Hengke,LEI Yongmei,LIANG Ji.Middleware for MPI based on RapidIO[J].Computer Engineering and Design,2008,29(21):5464-5467(in Chinese).[金亨科,雷詠梅,梁基.基于RapidIO的MPI設備層的設計與實現[J].計算機工程與設計,2008,29(21):5464-5467.] [5]Maloy J P.TIPC:Providing communication for Linux clusters[C]//Proceedings of the Ottawa Linux Symposium,2004. [6]Maloy J.Linux TIPC 1.7 programmers_guide_1.7.6.[EB/OL].http://tipc.sourceforge.net/doc/tipc_1.7_programmers_guide.pdf, 2008. [7]Mandvekar L,Qiao C,Husain M I.Enabling wide area single system image experimentation on the GENI platform[C]//Second Geni Research and Educational Experiment Workshop.IEEE Computer Society,2013:97-101. [8]JI Yinghui,CAI Wei,CAI Huizhi.Research and analysis of transparent inter process communication protocol[J].Computer Systems Applications,2010,19(3):76-79(in Chinese).[冀映輝,蔡煒,蔡惠智.TIPC透明進程間通信協議研究和應用[J].計算機系統應用,2010,19(3):76-79.] [9]SUN Zhongyi,JIN Tongbiao,YIN Jinyong.Performance measurement and analysis of communication protocols[J].Computer Systems Applications,2012,21(9):224-227(in Chinese).[孫忠義,金同標,殷進勇.通信協議性能測量與分析[J].計算機系統應用,2012,21(9):224-227.] [10]Goglin B,Moreaud S,Phanie.KNEM:A generic and scalable kernel-assisted intra-node MPI communication framework[J].Journal of Parallel & Distributed Computing,2013,73(2):176-188. [11]Andersson P,Maloy J,Krishnan S.A system and method for generating functional addresses:WO,EP2191634[P].2014. [12]Mehta K,Gabriel E.Multi-threaded parallel I/O for OpenMP applications[J].International Journal of Parallel Programming,2015,43(2):286-309. [13]WANG Yunsheng,WANG Jian,ZHOU Hong.TIPC communication architecture based on RapidIO[J].Telecommuni-cation Engineering,2012(12):1980-1983(in Chinese).[王運盛,王堅,周紅.基于RapidIO的TIPC通信軟件設計[J].電訊技術,2012(12):1980-1983.] [14]Goglin B,Moreaud S,Phanie.KNEM:A generic and scalable kernel-assisted intra-node MPI communication framework[J].Journal of Parallel & Distributed Computing,2013,73(2):176-188. [15]WANG Rui.Optimization of MPI communication library on KD60 platform[D].Hefei:University of Science and Technology of China,2011(in Chinese).[汪睿.KD60平臺MPI通信庫優化設計[D].合肥:中國科學技術大學,2011.]
3 實驗結果及分析




4 結束語