楊周凡,韓 林,李冰洋,謝景明,韓 璞,劉勇杰
(1.鄭州大學 信息工程學院,鄭州 450000;2.鄭州大學 國家超級計算鄭州中心,鄭州 450000)
隨著世界各國對清潔能源需求的不斷增長,供水管道在能源結構中發揮著重要的作用[1-2]。由于供水管道規模的擴大,導致拓撲結構也越來越復雜[3-4]。供水管道中數值的準確預測對整個管道建設和管道安全至關重要,供水管道系統的高效仿真是解決上述問題的重要手段[5]。初期人們可通過對數值方法進行改進,也可以使用更好的計算設備提升模擬計算效率,但是隨著管網拓撲結構大規模的擴大以及CPU 功耗墻的出現,該方法性能逐漸降低。
近年來,GPU 加速器開始廣泛用于科學計算,其提供了優越的計算處理能力和內存帶寬,并提高了計算效率[6-8]。文獻[8]提出一種加速單GPU 芯片上開放通道和管道組合流瞬態模擬的方法。在計算統一設備架構(CUDA)的線程級并行結構中,GPU 可以很好地利用其固有的并行性[9-10]。但是,對大規模管道網絡仿真計算時,仿真計算粒度密集,而傳統計算機受限于計算粒度密集的程序,可能會影響供水管網大規模數值模擬時的效率。“嵩山”超級計算機是我國自主研發的新一代E 級超級計算機,其采用符合超算國際主流趨勢的海光1 號CPU+海光1 號DCU 加速器的異構體系結構,所配備的DCU 加速器件使得該平臺更適合于部署高度密集型計算應用。因此,供水管網模擬系統在“嵩山”超級計算機平臺上進行模擬計算,可以進一步突破瓶頸提升計算性能。
盡管管網在超級計算機平臺上比傳統CPU 具有更高的計算效率,但單個DCU 節點的極限存儲和計算能力可能會影響管網在超擴展尺度上處理計算系統時的效率。在這種情況下,如果在多塊DCU 中進行計算,則需大幅擴展管網模擬計算的規模。
本文提出一種有效的并行化方案來提高管網的計算效率。面向“嵩山”超級計算機平臺,利用HIP-C 語言修改程序完成程序跨平臺移植,在單DCU 中實現計算的并發。針對管網中管道元件中數據依賴問題,對其進行數據劃分,并結合HIP 編程模型和消息傳遞接口,將多個DCU 加速器集成到網絡體系結構中,通過高效的混合并行化方案對管網進行優化[11]。
本節主要介紹管網管道拓撲結構,并描述HIP+MPI 混合編程。
管道運輸是各種清潔能源開發與輸送過程中一項重要的技術[12-13]。目前,管道運輸技術已有很多成熟的理論和模型,隨著計算機技術和網絡通信的飛速發展,能源運輸技術也逐漸實現了信息化,運輸管道仿真模擬系統應運而生。模擬仿真通過把數據訪問接口連接到系統,及時更新數據,將實時數據傳入到系統中進行計算,實現管網的動態模擬仿真[14-16]。
首先以管網實際拓撲圖為基礎來考慮管網模型,為清晰地描述管網的模擬計算過程,本文通過以下簡單管網進行說明。圖1 所示是一根獨立管道的兩個邊界節點。圖2 所示是一個簡單的管道系統,中間用一個非管道元件連接兩根管道,共有4 個臨界點。圖3 所示為擴大管道規模后構建一個閉環的管道系統,管道內由方程計算的值與非管道元件內由方程計算得出的結果通過邊界值計算進行數值交互,模擬仿真得出需要的數值。

圖1 單個管道圖Fig.1 Single pipeline diagram

圖2 簡單的管道系統Fig.2 Simple pipeline system

圖3 閉環的管道系統Fig.3 Closed-loop pipeline system
并行計算在不同的粒度層次優化,粒度一般分為粗粒度和細粒度。在集群上多個進程進行計算,進程間通過消息傳遞的方式進行通信[17-18]。由于MPI 的通信占用成本較高,因此更適合任務劃分清晰、通信不頻繁的粗粒度并行[19-20]。與MPI 相比,DCU 擅長大規模密集計算,可在細粒度上進行并行計算。本文結合MPI和DCU 的優點,通過MPI 消息傳遞機制控制多進程計算,實現粗粒度上的并發,并在每個進程中使用DCU實現線程級計算和細粒度上的并發[21]。
“嵩山”超級計算機一個節點內共有4 塊DCU,如果只在單DCU 中進行計算,每個節點的計算能力沒有被充分利用。為擴展DCU 計算規模,在實現多DCU 計算時,MPI+HIP 混合編程可以發揮優勢,為每一個DCU分別分配一個進程,使用MPI 控制多進程計算并進行通信[22-23]。進程之間使用消息傳遞接口傳輸數據,進程內采用HIP 技術進行線程級優化,實現粗粒度和細粒度的結合,提升科學計算的性能。HIP+MPI 混合編程結構如圖4 所示。

圖4 MPI+HIP 混合編程結構Fig.4 MPI+HIP mixed programming structure
管網模擬仿真系統在進行數值模擬時,大量的數據增加了計算時間,影響數值模擬的時間和精度。根據上文的內容可以了解到DCU 的計算能力,這可以解決目前模擬計算中所遇到的問題。下面將詳細介紹管網拓撲結構中管道與非管道的并行特性。參照圖3 結構中各元件計算的流程如圖5 所示。

圖5 管網元件計算流程Fig.5 Calculation procedure of pipeline network components
本文管道網絡仿真計算基于王海[13]提出的立體管網建模方法。將管網“對象化”,然后把管網元件的對象屬性賦予具體數值,得到每個元件與相鄰元件的連接屬性以及每個元件的初始狀態和邊界條件。管道元件和非管道元件在初始化后,可開始第1 個時間步長的計算,每次計算完成后,需要進行收斂分析,如果計算精度達到0.000 1%,則結束循環。這時能夠得到穩態時管道元件與非管道元件的流量、壓力和水力工況等數值。
在分析該程序代碼進行數值模擬計算時,首先需要設置循環條件,直到計算結果不發散才可計算結束。在外循環中先對非管道元件進行計算,在邏輯上將數組進行切分,數組不同的分段執行不同的非管道元件,使用hipDeviceSynchronize()函數進行同步,直到所有非管道元件計算完畢,才能對管道元件進行計算,然后同步直到所有管道元件計算完成。以上所有步驟在內循環每5 000 次后進行數值更新,并對計算結果進行收斂計算,直到計算結果收斂或達到最大循環次數,整個循環計算結束。在此過程中,各個非管道元件之間的計算是獨立的,管道元件之間的計算也沒有依賴,管道和管道、非管道與非管道之間有較高的并行度。因此,可以考慮在粗粒度上把各管道和非管道元件作為求解任務,將其傳輸到設備端進行并行計算。
供水管網仿真系統代碼是由C/C++語言編寫的,本文通過使用HIP-C 對代碼進行改寫,改寫后的代碼可以在“嵩山”超級計算機上運行并進行測試。通過測試可以發現,管道和非管道中水力計算部分耗時較長,一定程度上影響了模擬仿真計算的效率。因此,在工作中把管道和非管道中的計算部分在DCU 中進行并行計算,因為DCU 加速器對數據量較大、運算復雜的密集性計算有顯著優勢,所以對于供水管網模擬計算時把計算耗時較長的部分傳輸到DCU 中,計算效率有了顯著的提升。供水管網仿真系統在異構架構中的模擬實現流程如圖6 所示。
結合圖6 分析在程序中需要讀取管道和非管道元件中的數據,并寫入不同的結構體數組,然后定義結構體指針,動態分配各個管道和非管道結構體指針的內存,將主機端內存的管道元件和非管道元件的結構體數組傳輸到DCU 加速器設備內存中,并對其進行初始化。管網中管道元件和非管道元件需循環計算,直到達到收斂條件或最大循環次數方可跳出循環結束計算。在外循環中,對管網中各元件循環計算時,管道元件和非管道元件將DCU 加速器映射到block 塊中,每個block 中可以根據實際應用分配線程,非管道元件和管道元件計算時按順序計算。首先計算非管道元件并同步,當所有非管道元件計算完畢之后開始管道的計算,同理,管道計算后也需要同步。以上操作以5 000 次為基準,開啟內循環,每循環計算5 000 次,所有元件進行一次更新,并對其中的二通、三通、四通進行收斂條件判斷,若達到收斂條件,則跳出循環;否則再次重復上述步驟對非管道和管道進行并行操作,直到外循環結束,跳出循環,將最終的計算結果從設備端傳回到主機端,重新關聯非管道元件和管道,直至模擬計算結束。

圖6 異構版本供水管網仿真系統模擬流程Fig.6 Simulation procedure of water supply pipeline network simulation system of heterogeneous versions
對于小規模的管道網絡,可以實現在單DCU 中計算,當管道網絡規模逐漸擴大時,單DCU 中計算規模不能滿足仿真計算的需求,因此將單DCU 擴展到多DCU 中進行模擬計算。
供水管網模擬仿真系統在多DCU 中的實現,合理的管道劃分方式和數據通信傳輸尤其重要。
管網數據必須根據DCU 節點處理管道數據,并將這些數據逐個寫入DCU,而不是計算整個過程中的所有管道數據。在程序優化過程中直接將管道數據分成兩個部分,并將這兩個部分的數據分別寫入到兩塊DCU 內存中進行計算,但在計算過程中程序運行到一半發生了中斷,測試調試發現在對管道數據循環讀取時,讀到一部分管道數據后循環中斷,發生數據缺失的情況。經過分析,管道之間數據交互密切,各個DCU 中一部分管道和非管道元件之間存在數據依賴問題。在對管道數據進行讀取時,無法實現跨進程讀取操作,DCU 之間也無法進行跨設備的數據訪問。為解決該問題,需要使用消息傳遞接口(MPI)使相關進程之間進行通信,實現數據跨進程通信交互。
使用MPI 控制兩進程計算并進行通信時,將管道元件分成兩部分,同時需要找到一部分管道元件作為兩進程中的公有部分,傳回到主機端通信傳遞。在此項目組的成員提出一種一維分割方法,該方法將整個管道和非管道數據分成兩個部分,管道數據按組號被分割為三部分:GroupId=0,GroupId=1 和GroupId=2。把分組GroupId=1 的管道數據寫入到DCU0 中,然后將分組GroupId=2 的管道數據寫入到DCU1 中,管道分割圖如圖7 所示。從圖7 可以看出,管道數據被相對均勻地分配到了兩塊DCU 加速器中,在兩塊DCU 中有一部分管道數據GroupId=0屬于兩塊DCU 中的公有部分。這一部分數據需要同時寫入到兩塊DCU 中,GroupId=0 的管道數據作為連接兩部分管道數據的橋梁,在管道元件和非管道元件計算5 000 次后,將GroupId=0 的管道數據從DCU0 中傳回到主機端進行通信,然后再傳回到DCU1中,最后對管道元件刷新,代表一次通信完成。

圖7 管道分割圖Fig.7 Pipeline segmentation diagram
本節主要描寫MPI 的具體實現以及在實現過程中遇到的問題。
3.2.1 數據類型重定義
數據類型在數據結構中的定義是一組性質相同的值的集合以及定義在這個值集合上的一組操作的總稱。變量用來存儲值,它們有名字和數據類型。結合供水管網仿真模擬的代碼,管道和非管道元件被封裝成結構體,MPI 需要知道結構體的數據類型才能實現通信傳輸。因此,需要對結構體實現數據類型重定義。
本文對程序中管道接口和管道的結構體進行重定義。首先程序中使用MPI_Datatype 定義新的數據類型名稱,通過blocklens 數組定義管道接口和管道中每個數據類型的長度,并根據oldTypes 數組描述管道接口和管道舊數據的類型,通過MPI_Address指定數組中每個塊中的偏移量。然后運用MPI_Type_struct 生成新的管道接口和管道數據類型。最后采用MPI_Type_commit 提交注冊新的數據類型&PipeStruct 和&PipePortStruct。
3.2.2 MPI 實現過程
在MPI 信息傳遞接口進行通信前,應先對分割好的管道元件和非管道元件實現讀取和寫入操作。利用一維分割方法對各個元件進行分割后,通過MPI_Comm_rank()獲取進程號,進程號控制各個進程對非管道元件和管道的讀取,將各自的數據分別讀取到各進程的結構體數組中。本文主要使用數組指針進行讀寫操作,數組指針是動態分配空間,使用更加靈活,相比直接使用數組,其代碼擴展性更好。在讀寫完成之后,再由hipMemcpy()將其分別傳入到各自的DCU 進行計算。由于MPI 的通信是在主機端進行的,需要使用hipMemcpy()來控制設備端與主機端之間數據的傳輸。圖8 所示為MPI 通信時數據傳輸的過程。

圖8 MPI 通信過程Fig.8 MPI communication process
MPI 在實現過程中,主機端使用MPI_Comm_rank()獲取當前的進程號,調用hipGetDevice()獲取DCU 加速器的設備編號,以此確定進程編號和設備編號的對應關系。每個進程控制一個DCU,在對應的設備上進行數據顯存的劃分,完成主機端向設備端計算數據的傳輸,并各自啟動內核函數;每個進程設置自己私有的主機端和設備端的數據指針,其中管道元件的數據被分為三部分,GroupId=0 是公有部分,這一部分管道元件數據使用hipMemcpy(DTH)從設備端傳輸到主機端被單獨寫入到Host_PublicPipeArray 數組中,MPI 在管道和非管道分別計算5 000 次后,將共有數據通過DCU 私有的設備端數據指針拷貝回私有主機端,在私有主機端進行數據的通信及更新,并進行收斂性檢查,在主機端中結束通信后分別拷貝到私有設備端中,之后對所有非管道元件更新一次。在外循環進程中,進程對各自的管道和非管道元件每進行5 000 次密集計算都會使用MPI 通信接口進行傳輸通信并更新所有元件,直至供水管網模擬計算結果收斂,計算結束通信完成。圖9 所示為MPI 通信傳遞實現過程。

圖9 MPI 通信實現過程Fig.9 MPI communication realization process
從單DCU 加速器擴展到多DCU 加速器,由MPI控制多進程計算的實現解決了DCU 自身的偽并行,完成了大規模數據多進程的并發實現。多DCU 的實現擴大了密集計算的規模,突破了單DCU 加速器計算資源的限制,對以后大規模程序的計算需求具有重要意義。
“嵩山”超級計算機系統的操作系統為Centos-6.7,集群作業管理系統為Gridview,CPU 編譯器為gcc/g++-7.3.1,DCU 加速器編譯器為hipcc-2.9.6,MPI 版本為hpcx-2.4.1,CPU 處理器為英特爾?酷睿?i9-9980XE。
本文在“嵩山”超級計算機平臺單節點單DCU上進行正確性驗證。首先對CPU+DCU 異構實現的供水管網模擬仿真計算進行小規模數據測試,將記錄模擬出的數值與管網串行實現的模擬仿真結果進行比較,經對比發現,兩者計算結果的數值變化在允許范圍內,通過了正確性驗證。
4.1.1 異構實現結果對比
將供水管網模擬實現的異構版本與在CPU 處理器英特爾?酷睿?i9-9980XE 上的運行結果進行對比,為使描述清晰簡潔,將在單DCU 內優化方法簡稱為方法1,在多DCU 內優化方法簡稱為方法2。通過輸入小規模器件數量和大規模器件數量,并在不同的計算平臺上進行仿真計算測試。如表1 所示,選取器件規模數分別為10 000、30 000。

表1 不同規模器件在CPU 和方法1 下的結果對比Table 1 Comparison of results of different scale devices in CPU and method 1
由表1 數據可以看出,在器件數為10 000 時,在DCU 加速器上的加速比為5.065,隨著計算規模的增加,當輸入器件數為30 000 時,加速比達到了9.833。分析其原因,是因為在小規模數據計算時,不能充分利用DCU 加速器的并行資源,計算性能有一定幅度的提升,但不能達到最優。當器件數量增多時,DCU加速器在大規模密集計算的計算優勢突出,加速效果明顯提升。實驗結果證明了CPU+DCU 異構實現的供水管網模擬計算在“嵩山”超級計算機平臺的單DCU 加速器環境中,加速效果十分顯著,在保證相同計算精度的前提下,計算速度提升5~10 倍,且管網模型規模越大,DCU 加速效果則越顯著。
表2 所示是GPU 異構平臺上的運行結果與方法1進行對比,加速比提升了2~3 倍。可以看出,在“嵩山”超級計算機上的移植相比顯卡為GT 730 的GPU異構平臺仍有顯著的優勢。

表2 不同規模器件在GPU 和方法1 下的結果對比Table 2 Comparison of results of different scale devices in GPU and method 1
本節實驗驗證了供水管網模擬仿真系統在不同平臺的測試結果,表明“嵩山”超級計算機更適合于大規模仿真計算,且其相對于以往實施x86 平臺或GPU 異構平臺,計算性能都有明顯提升。
4.1.2 多DCU(方法2)實現測試分析
由于越來越多管道的建立,管網拓撲復雜,計算量大,單DCU 的計算規模已經不能滿足龐大的管網數據計算量。本節基于MPI+HIP 模型選擇供水管網仿真計算在多DCU 上的實現進行實驗,將在單DCU 上管網模擬仿真運行的時間作為基準,測試該模擬程序在單節點內多個DCU 上運行的并行效率,如表3 所示。

表3 不同規模器件在方法1 和方法2 下的結果對比Table 3 Comparison of results of different scale devices under method 1 and method 2 s
在輸入管器件數量分別為10 000、30 000 時,DCU 單卡加速與DCU 多卡加速速度相當,多卡加速效果略優于單卡,但當面對超大規模管網模型時,多卡加速效果將明顯優于單卡環境。原因是由于在MPI 進行通信傳輸時,需要將管網中管道和非管道元件從設備端傳輸到主機端進行數據通信,然后再傳回到設備端。在輸入規模少的管道和非管道數據進行計算時,使用hipMemcpy()進行傳輸所占用的時間較長,核函數內密集計算占比較小,性能提升不明顯,但是隨著輸入管網規模的增大,在核函數內計算占比遠超過傳輸占比時,加速比取得大幅提升。
表4 所示是將在CPU 加速器上的運行結果與DCU 多卡加速結果進行對比,加速比提升了5~10 倍。從表4 可以看出,將數據規模擴展到多塊DCU 中測試結果取得較優的性能,隨著規模的擴大,加速比與規模的擴大成正比。

表4 不同規模器件在CPU 和方法2 下的結果對比Table 4 Comparison of results of different scale devices under CPU and method 2
實驗結果證明了基于HIP 編程模型和MPI 實現的供水管網模擬仿真計算在“嵩山”超級計算機系統的多DCU 上具有良好的可拓展性,對供水管網在“嵩山”超級計算機平臺上實現規模擴展具有重要的意義。
本文利用HIP-C 語言實現供水管網模擬仿真計算在“嵩山”超級計算機平臺的移植,通過對管道和非管道元件的數據進行劃分,并基于CPU+DCU 異構架構,利用HIP 編程模型和消息傳遞接口控制DCU 的并發和多進程之間數據的通信傳遞,擴展管網仿真計算的規模,同時提升模擬實現的效率。實驗結果驗證了本文優化方法的有效性。下一步將進行管網內核函數計算部分的優化工作,研究擴展核函數內管道和非管道元件的并行特性,以達到提升管網仿真計算性能的目標。