張馭洲,曹武迪,卜景德,譚光明,吉 青
(1.中國(guó)科學(xué)院理論物理研究所理論物理先進(jìn)計(jì)算聯(lián)合實(shí)驗(yàn)室,北京 100190; 2.中國(guó)科學(xué)院計(jì)算技術(shù)研究所計(jì)算機(jī)體系結(jié)構(gòu)國(guó)家重點(diǎn)實(shí)驗(yàn)室, 北京 100190)
分子動(dòng)力學(xué)MD(Molecular Dynamics)[1]模擬是利用計(jì)算機(jī)模擬原子或分子運(yùn)動(dòng)的方法,通過模擬微觀層面大量原子或分子的運(yùn)動(dòng)來研究物質(zhì)的結(jié)構(gòu)和性質(zhì)。由于其可以方便地模擬實(shí)驗(yàn)方法難以測(cè)定的微觀結(jié)構(gòu)和物理過程而廣泛應(yīng)用于生物、化學(xué)、醫(yī)藥和材料等研究領(lǐng)域。經(jīng)典MD模擬方法建立在牛頓力學(xué)基礎(chǔ)之上,通過計(jì)算模擬體系中大量原子或分子之間的相互作用,最終得到整個(gè)體系的宏觀統(tǒng)計(jì)信息。當(dāng)前具有實(shí)際應(yīng)用意義的MD模擬通常需要對(duì)包含至少數(shù)萬、數(shù)十萬粒子的體系進(jìn)行百萬乃至上億時(shí)間步的模擬計(jì)算,在空間和時(shí)間尺度上都對(duì)計(jì)算能力有著極高的要求,因此,一直以來,MD都是高性能計(jì)算HPC(High Performance Computing)領(lǐng)域的一個(gè)重要應(yīng)用方向。
GROMACS[2]是一個(gè)應(yīng)用廣泛的開源MD模擬軟件。在眾多的開源MD軟件之中,GROMACS以高性能和高效率著稱。當(dāng)前世界上最大的分布式計(jì)算項(xiàng)目Folding@home[3]使用的計(jì)算引擎就是GROMACS。GROMACS擁有高度優(yōu)化的CPU計(jì)算代碼,支持通過MPI+OpenMP進(jìn)行大規(guī)模并行計(jì)算,還通過CUDA支持NVIDIA GPU,并通過OpenCL支持其他加速設(shè)備,但OpenCL版本對(duì)新功能的支持一般落后于CUDA。當(dāng)前最新的GROMACS 2020系列已經(jīng)通過CUDA將MD模擬中計(jì)算量最大的3種作用力類型——短程非成鍵作用力、長(zhǎng)程作用力和成鍵作用力均實(shí)現(xiàn)了GPU加速計(jì)算,性能得到了進(jìn)一步提高[4]。而OpenCL版本目前尚不支持成鍵力在GPU上的計(jì)算。
ROCm(Radeon Open Compute)[5]是AMD推出的一個(gè)開源高性能異構(gòu)計(jì)算平臺(tái),提供了包括GPU驅(qū)動(dòng)、編譯器、運(yùn)行時(shí)、數(shù)學(xué)庫(kù)、性能分析與調(diào)試工具在內(nèi)的一整套編程開發(fā)和程序運(yùn)行環(huán)境。ROCm提供了一個(gè)名為HIP(Heterogeneous-computing Interface for Portability)的編程模型及語言[6],使用HIP編寫的應(yīng)用程序可以通過ROCm平臺(tái)在AMD GPU上運(yùn)行。HIP的應(yīng)用層API與CUDA相似,可以較為方便地將現(xiàn)有CUDA程序轉(zhuǎn)碼為HIP程序,從而將只能在NVIDIA GPU上運(yùn)行的應(yīng)用移植到AMD GPU上。根據(jù)媒體披露,美國(guó)的3臺(tái)E級(jí)高性能計(jì)算機(jī)中,有2臺(tái)都將采用AMD GPU。
作為開源平臺(tái),ROCm擁有比閉源的CUDA更好的靈活性,但其生態(tài)的建設(shè)離不開豐富的應(yīng)用的支持。本文通過將最新的GROMACS 2020系列轉(zhuǎn)碼為HIP代碼,實(shí)現(xiàn)了向ROCm平臺(tái)的移植,并通過對(duì)代碼的一系列優(yōu)化,在目標(biāo)算例上獲得了相對(duì)初始轉(zhuǎn)碼版本約2.8倍的加速比。據(jù)我們所知,這是目前世界范圍內(nèi)第一個(gè)實(shí)現(xiàn)最新版GROMACS完整功能的HIP版本。
本文主要有以下貢獻(xiàn):
(1)在ROCm平臺(tái)首次實(shí)現(xiàn)了GROMACS 2020系列的完整功能,一方面為ROCm平臺(tái)的生態(tài)系統(tǒng)添加了GROMACS這一應(yīng)用廣泛的HPC軟件,另一方面移植的過程也可為其他應(yīng)用的移植提供參考。
(2)以有代表性的算例為目標(biāo),在單結(jié)點(diǎn)內(nèi)分析了其計(jì)算熱點(diǎn)與瓶頸,進(jìn)行了針對(duì)性的性能優(yōu)化,獲得了相對(duì)初始轉(zhuǎn)碼版本約2.8倍的加速比,其優(yōu)化思路與方法也可以為其他GPU應(yīng)用的優(yōu)化工作提供借鑒;通過多結(jié)點(diǎn)擴(kuò)展性測(cè)試,分析了擴(kuò)展性方面的瓶頸,為后續(xù)優(yōu)化打下了基礎(chǔ)。
HIP是ROCm 運(yùn)行時(shí)環(huán)境之上的一層很薄的封裝,它提供了一系列代碼自動(dòng)檢查與轉(zhuǎn)換工具,可以自動(dòng)檢查源文件中的CUDA API并轉(zhuǎn)換為相應(yīng)的HIP API,因此簡(jiǎn)單程序的移植已經(jīng)十分方便。然而,大型的應(yīng)用程序文件數(shù)量多,結(jié)構(gòu)復(fù)雜,不僅代碼文件需要轉(zhuǎn)換,編譯構(gòu)建工具也需要修改,因此往往需要更多人工調(diào)試才能成功移植。
GROMACS經(jīng)歷了二十多年的不斷開發(fā)與迭代,現(xiàn)在已經(jīng)成為了一個(gè)龐大而復(fù)雜的應(yīng)用軟件,代碼量已達(dá)百萬行量級(jí)[2]。GROMACS 2020.2版本源代碼基本組織結(jié)構(gòu)如圖1所示。主要的源碼文件都位于src/gromacs目錄下。GROMACS使用CMake[7]進(jìn)行編譯構(gòu)建,頂層目錄的cmake目錄下是配置各種編譯參數(shù)的cmake文件,在各級(jí)源碼目錄下都包括一個(gè)CMakeLists.txt文件,用于管理本級(jí)目錄下源碼文件的編譯。通過使用HIP提供的工具完成自動(dòng)代碼轉(zhuǎn)換之后,本文對(duì)代碼和構(gòu)建系統(tǒng)進(jìn)行了調(diào)試修改,完成了編譯,構(gòu)建的GROMACS可以通過所有自帶的單元測(cè)試。
Figure 1 Source code organization of GROMACS 2020.2圖1 GROMACS 2020.2 源代碼基本組織結(jié)構(gòu)
為保持與先前工作的一致性[8],本文使用的算例是 [C16MP]+[Br3]-。首先驗(yàn)證HIP版GROMACS的計(jì)算正確性,然后作為性能基準(zhǔn),進(jìn)行后續(xù)的代碼優(yōu)化。該算例模擬體系為離子液體體系,由1 440對(duì)離子構(gòu)成,原子數(shù)為95 040,有大量成鍵相互作用(bonded interaction)和非成鍵相互作用nb(non-bonded interaction)。測(cè)試使用的軟硬件版本及型號(hào)列于表1。分別使用GROMACS 2020.2原版CPU程序、原版OpenCL程序和本文移植的HIP版本程序,采用相同的模擬參數(shù)(版本功能特性相關(guān)參數(shù)除外)將測(cè)試算例運(yùn)行5萬時(shí)間步,運(yùn)行的命令行參數(shù)列于表2。以原版CPU程序5萬步平均計(jì)算結(jié)果為基準(zhǔn),OpenCL版和HIP版的相對(duì)誤差結(jié)果都在同一數(shù)量級(jí),并且都在MD允許的波動(dòng)范圍內(nèi),證明了HIP版計(jì)算結(jié)果的正確性;最后1萬步統(tǒng)計(jì)的性能數(shù)據(jù)如表3所示。
Table 1 Software hardware and versions and models used in the test表1 本文測(cè)試使用的軟硬件版本及型號(hào)
Table 2 Command line parameters used in the test表2 測(cè)試中使用的命令行參數(shù)
Table 3 Performance comparison of three versions of GROMACS on 10 000 steps running表3 3個(gè)版本GROMACS運(yùn)行10 000步的性能數(shù)據(jù)
可見原版的OpenCL版本比CPU版本約有67.9%的加速,而移植的HIP版本性能甚至略低于CPU版本。
MD的計(jì)算量主要來源于粒子之間的短程非成鍵相互作用(short-ranged non-bonded interaction)、長(zhǎng)程相互作用(通過PME(Particle-Mesh-Ewald)方法計(jì)算)和成鍵相互作用。本文移植的HIP版GROMACS已經(jīng)將這3種作用力的計(jì)算全部都在GPU上實(shí)現(xiàn)了,因此,需要一個(gè)GPU核函數(shù)性能分析工具來考察程序的性能瓶頸。ROCm提供了rocprof[9]工具來完成這一工作。rocprof可以在runtime層抓取GPU的運(yùn)行數(shù)據(jù),獲得包括核函數(shù)的發(fā)起與結(jié)束時(shí)間、內(nèi)存拷貝的起始、結(jié)束以及數(shù)據(jù)量等信息,還可以結(jié)合Chrome瀏覽器的tracing工具實(shí)現(xiàn)可視化。
Figure 2 Time lines of kernel of the first ported HIP code圖2 HIP初始版本的核函數(shù)時(shí)間線
圖2為HIP初始版本的核函數(shù)時(shí)間線。圖2中顯示的核函數(shù)執(zhí)行順序與GROMACS計(jì)算流程一致,但是每個(gè)函數(shù)的執(zhí)行時(shí)間都異常長(zhǎng),因此本文后續(xù)著重對(duì)每個(gè)核函數(shù)進(jìn)行了優(yōu)化。
3.3.1 bonded核函數(shù)優(yōu)化
bonded核函數(shù)是一個(gè)函數(shù)模板,在一個(gè)50時(shí)間步的運(yùn)行中,其不同的實(shí)例調(diào)用次數(shù)、平均運(yùn)行時(shí)間及總時(shí)間如表4所示。
Table 4 Performance analysis results of the bonded kernel表4 bonded 核函數(shù)性能分析結(jié)果
不同的模板參數(shù)下,bonded核函數(shù)的運(yùn)行時(shí)間差異較大??疾炱浯a,發(fā)現(xiàn)不同模板參數(shù)的實(shí)例的差異主要在于是否計(jì)算位力(virial,作用于粒子上的合力與粒子矢徑的標(biāo)積)和能量。位力和能量的計(jì)算需要將體系中所有粒子的貢獻(xiàn)都累加起來,GROMACS原版的CUDA代碼直接使用atomicAdd函數(shù)將每個(gè)線程的計(jì)算結(jié)果累加到GPU全局內(nèi)存中的變量,這一操作在MI50 GPU上導(dǎo)致了嚴(yán)重的性能下降。MI50 GPU硬件支持32位整型的原子加操作,但是浮點(diǎn)型原子加操作是通過一個(gè)CAS(Compare-And-Swap)循環(huán)實(shí)現(xiàn)的,性能較差,大量對(duì)全局內(nèi)存地址的原子加操作會(huì)嚴(yán)重降低程序性能。針對(duì)這種情況,本文將bonded核函數(shù)中對(duì)位力和能量的歸約進(jìn)行了修改,首先在block內(nèi)部利用共享內(nèi)存進(jìn)行歸約,然后再使用原子加在block之間進(jìn)行歸約。利用共享內(nèi)存上較快的原子加操作代替了大量直接操作全局內(nèi)存地址的原子加操作,相關(guān)核函數(shù)性能有了大幅提升。
此外,本文還修改了bonded核函數(shù)的發(fā)起參數(shù),將原來256線程的block尺寸縮減為64線程,性能得到了進(jìn)一步提高。MD中成鍵力的計(jì)算量與非成鍵力相比要小很多,并且有較多邏輯判斷,嚴(yán)格意義上并不適合GPU計(jì)算。GROMACS原版的CUDA代碼中,bonded核函數(shù)有一個(gè)包括8種成鍵力的switch語句。當(dāng)某些warp發(fā)生分支,整個(gè)block的計(jì)算都將被減慢。將block尺寸減小到ROCm平臺(tái)上warp(wavefront)的尺寸,就完全消除了正常warp對(duì)發(fā)生分支的warp的等待,從而進(jìn)一步縮短了bonded核函數(shù)的平均執(zhí)行時(shí)間。
圖3為兩步優(yōu)化前后bonded核函數(shù)的性能。由于原來原子加操作只有在計(jì)算位力和能量時(shí)才會(huì)執(zhí)行,因此第1步減少原子加操作的優(yōu)化大幅減少了模板參數(shù)為〈true,true〉的核函數(shù)實(shí)例的運(yùn)行時(shí)間,而其他2種實(shí)例性能不變。通過減小block尺寸的進(jìn)一步優(yōu)化,bonded核函數(shù)的3種實(shí)例性能都得到大幅提升,其中后2種實(shí)例執(zhí)行時(shí)間甚至降為0,是因?yàn)閱蝹€(gè)核函數(shù)的執(zhí)行時(shí)間已經(jīng)小于性能分析工具所能抓取的最小時(shí)間間隔。
Figure 3 Average execution time of bonded kernels before and after optimization圖3 優(yōu)化前后bonded核函數(shù)的平均執(zhí)行時(shí)間
3.3.2 PME核函數(shù)優(yōu)化
PME部分的2個(gè)主要核函數(shù)pme_solve_kernel和pme_spline_and_spread_kernel中也使用了直接操作GPU全局內(nèi)存的浮點(diǎn)型原子加操作,本文也對(duì)這2個(gè)函數(shù)進(jìn)行了優(yōu)化嘗試。
(1)pme_solve_kernel。
當(dāng)需要計(jì)算位力和能量時(shí),pme_solve_kernel核函數(shù)的每個(gè)線程需要計(jì)算6個(gè)位力分量和1個(gè)能量變量,這7個(gè)量需要全局累加。原版代碼首先使用shuffle指令和共享內(nèi)存,將每個(gè)線程所計(jì)算的7個(gè)變量的結(jié)果歸約到線程所屬block的前7個(gè)線程,然后每個(gè)block的前7個(gè)線程使用浮點(diǎn)型原子加操作將結(jié)果歸約到全局內(nèi)存。盡管已經(jīng)通過shuffle指令和共享內(nèi)存歸約了block內(nèi)的結(jié)果,但由于block數(shù)量眾多,所有的block都對(duì)全局內(nèi)存中同樣7個(gè)地址進(jìn)行原子加操作,仍然嚴(yán)重影響了性能。
Figure 4 Schematic diagram of pme_solve_kernel optimization 圖4 pme_solve_kernel優(yōu)化示意圖
為了避免使用性能不佳的原子加操作,本文在原來保存7個(gè)位力和能量變量的GPU全局內(nèi)存地址之后再額外申請(qǐng)一段內(nèi)存,其長(zhǎng)度為pme_solve核函數(shù)的block數(shù)乘以7個(gè)float變量大小。pme_solve_kernel在計(jì)算得到7個(gè)位力和能量變量之后不再向全局內(nèi)存歸約,而是直接寫入額外申請(qǐng)的全局內(nèi)存中,按照分量的種類寫入其對(duì)應(yīng)的內(nèi)存塊,每種分量數(shù)量等于pme_solve_kernel的block數(shù),總共7種分量。在全部的pme_solve_kernel核函數(shù)完成計(jì)算和全局內(nèi)存寫入之后,使用另外一個(gè)單獨(dú)的核函數(shù)讀取pme_solve_kernel核函數(shù)寫入全局內(nèi)存的結(jié)果,使用shuffle指令和共享內(nèi)存進(jìn)行block內(nèi)的歸約。該單獨(dú)歸約的核函數(shù)的block尺寸設(shè)置為MI50 GPU允許的最大blockSize 1 024,并且只發(fā)起一個(gè)block,這樣block內(nèi)的歸約結(jié)果就是最終結(jié)果,從而完全避免了對(duì)全局內(nèi)存原子加操作的使用。圖4為pme_solve_kernel優(yōu)化示意圖。
Figure 5 Average execution time of the pme_solve_kernel before and after optimization圖5 pme_solve_kernel核函數(shù) 優(yōu)化前后核函數(shù)平均執(zhí)行時(shí)間
圖5為優(yōu)化前后pme_solve_kernel不同實(shí)例的平均執(zhí)行時(shí)間??梢妼?duì)原子加操作的優(yōu)化大幅提升了計(jì)算位力和能量的核函數(shù)實(shí)例的性能,其執(zhí)行時(shí)間已經(jīng)接近不計(jì)算位力和能量的核函數(shù)實(shí)例。當(dāng)然,為了替代原子加,本文引入單獨(dú)歸約核函數(shù),該核函數(shù)平均執(zhí)行時(shí)間約15 μs,因此總體上仍然提升了代碼性能。
(2)pme_spline_and_spread_kernel。
pme_spline_and_spread_kernel核函數(shù)的一個(gè)功能是將每個(gè)粒子的電荷分散到周圍n3個(gè)FFT(Fast Fourier Transform)網(wǎng)格點(diǎn)上,n為B樣條插值的階數(shù)。該操作在block內(nèi)的原子加操作寫入同一全局內(nèi)存地址的比例很少,而不同的block之間則有較多訪問同一全局內(nèi)存地址的原子加操作,因此無法通過先行歸約block內(nèi)的線程來減少原子加操作的數(shù)量。而對(duì)于在pme_solve_kernel中使用的方法,即通過單獨(dú)的歸約核函數(shù)來避免原子加操作,這里也不再有效。這是因?yàn)?,從歸約的目標(biāo)地址和每個(gè)目標(biāo)地址上所需歸約的元素的數(shù)量來看,pme_solve_kernel的原子加操作是“密集型”:歸約目標(biāo)為7個(gè)全局內(nèi)存地址,每個(gè)地址需要累加至少上千個(gè)元素;而pme_spline_and_spread_kernel的原子加操作是“稀疏型”:歸約目標(biāo)為整個(gè)體系FFT網(wǎng)格的所有格點(diǎn),每個(gè)格點(diǎn)需要累加的元素?cái)?shù)目不定,而是根據(jù)該點(diǎn)周圍的帶電粒子密度而變化的,一般多則幾十個(gè),少的甚至為零,而FFT網(wǎng)格的數(shù)目卻很大,以本算例為例,F(xiàn)FT網(wǎng)格尺寸為72 × 48 × 192,共663 552個(gè)格點(diǎn)。pme_solve_kernel采用的單獨(dú)歸約核函數(shù)方法,在這種情況下將變得極為低效:首先,需要額外申請(qǐng)的內(nèi)存空間很大,對(duì)于本例來說,即使假設(shè)每個(gè)目標(biāo)地址最多只需要累加10個(gè)元素,總共也需要6 635 520個(gè)float數(shù),超過25 MB的全局內(nèi)存;而且由于每個(gè)時(shí)間步每個(gè)目標(biāo)地址所需累加的元素個(gè)數(shù)可能改變,每一步計(jì)算都需要將這些內(nèi)存全部清零。其次,對(duì)于這樣大量的數(shù)據(jù),采用單獨(dú)的歸約核函數(shù)從全局內(nèi)存讀入再歸約,也非常耗時(shí)。本文實(shí)現(xiàn)了該方法并進(jìn)行了測(cè)試,結(jié)果表明,在pme_spline_and_spread_kernel核函數(shù)中使用單獨(dú)的歸約核函數(shù)后,性能比原來直接使用原子加更差。因此,本文對(duì)于該核函數(shù)沒有進(jìn)行進(jìn)一步的優(yōu)化,仍然使用原版直接原子加操作的方案。這一案例也體現(xiàn)了從硬件上直接加速原子加操作的必要性。
3.3.3 nb核函數(shù)優(yōu)化
短程非成鍵相互作用(nb)是MD中計(jì)算量最大的部分,并且非常適合GPU計(jì)算,因此也是GROMACS最早實(shí)現(xiàn)GPU計(jì)算的部分。GROMACS為nb設(shè)計(jì)了一個(gè)精巧的算法[10],在CPU和GPU上都獲得了良好的性能。隨著GROMACS支持的模擬種類的不斷豐富,nb核函數(shù)已經(jīng)成為了一個(gè)包含數(shù)十種版本的函數(shù)模板。本文針對(duì)MI50 GPU的硬件特性,對(duì)[C16MP]+[Br3]-算例所使用的nb核函數(shù)實(shí)例代碼進(jìn)行了2個(gè)方面的優(yōu)化,獲得了一定的性能提升。
(1)減少原子加操作數(shù)量。
nb核函數(shù)同樣使用了訪問全局內(nèi)存地址的浮點(diǎn)型原子加操作,分別用于歸約每個(gè)粒子受到的鄰居粒子的作用力和偏移力。原版CUDA代碼中,對(duì)于大部分CUDA設(shè)備,nb核函數(shù)的每個(gè)block都是64線程(計(jì)算能力為3.7時(shí)為128線程),占用2個(gè)warp,因此在歸約時(shí)也是按照2個(gè)warp進(jìn)行設(shè)計(jì)。在MI50 GPU上,nb核函數(shù)剛好只占用1個(gè)warp,因此我們把相關(guān)的歸約均改為warp內(nèi)的shuffle操作,將訪問全局內(nèi)存的浮點(diǎn)型原子加操作數(shù)量減少了一半,提高了該核函數(shù)的性能。
(2)減少寄存器使用量。
盡管GPU被設(shè)計(jì)為用于大規(guī)模的并行計(jì)算,但是其并行性也是受硬件資源數(shù)量限制的,主要的限制因素是核函數(shù)中共享內(nèi)存以及寄存器文件的使用量。nb是一個(gè)規(guī)模較大的核函數(shù),使用了較多的寄存器變量。本文將編譯該核函數(shù)得到的目標(biāo)文件反匯編后,發(fā)現(xiàn)其占用的寄存器數(shù)量達(dá)到97個(gè),在ROCm平臺(tái),這一寄存器使用量導(dǎo)致MI50 GPU上的每個(gè)單指令多數(shù)據(jù)SIMD(Single Instruction Multiple Data)計(jì)算組只能并發(fā)執(zhí)行2個(gè)warp。較低的并發(fā)數(shù)使得程序運(yùn)行過程中某些指令(例如原子加操作)的延遲難以得到掩蓋。
nb核函數(shù)雖然使用的寄存器數(shù)量較多,但共享內(nèi)存的用量卻相對(duì)較少,如能將部分寄存器變量轉(zhuǎn)為使用共享內(nèi)存,有望提高并發(fā)數(shù)。然而,共享內(nèi)存的讀寫速率仍然是遠(yuǎn)低于寄存器變量的,實(shí)際驗(yàn)證中發(fā)現(xiàn),在循環(huán)中有寫操作的寄存器變量轉(zhuǎn)移到共享內(nèi)存后核函數(shù)性能反而下降。經(jīng)過對(duì)代碼的分析發(fā)現(xiàn),nb_sci是一個(gè)包含4個(gè)int分量的結(jié)構(gòu)體變量,它在所有循環(huán)開始之前賦值1次,后續(xù)的循環(huán)之中只有讀操作,沒有寫操作。將nb_sci變量轉(zhuǎn)移到共享內(nèi)存之后,nb核函數(shù)寄存器使用量降低為81個(gè),這樣SIMD并發(fā)的warp數(shù)增長(zhǎng)為3,經(jīng)過實(shí)際測(cè)試,執(zhí)行次數(shù)占絕對(duì)多數(shù)的nb核函數(shù)實(shí)例nbnxn_kernel_ElecEw_VdwLJCombLB_F_cuda性能有約7%的提升,因此,在另外2個(gè)nb核函數(shù)性能基本不變甚至略有下降的情況下,程序的總體性能仍有提升。圖6為優(yōu)化前后nb核函數(shù)實(shí)例的平均執(zhí)行時(shí)間。
Figure 6 Average execution time of the nb kernels before and after optimization圖6 優(yōu)化前后nb核函數(shù)的平均執(zhí)行時(shí)間
通過對(duì)MD模擬中計(jì)算量最大的3部分(即短程非成鍵相互作用、長(zhǎng)程相互作用以及成鍵相互作用)的GPU核函數(shù)nb、PME和bonded的優(yōu)化,[C16MP]+[Br3]-算例的性能從最初的13.109 ns/d增長(zhǎng)為36.980 ns/d,提升182.1%。
表5列出了實(shí)施一系列優(yōu)化措施后算例的整體運(yùn)行時(shí)間,時(shí)間統(tǒng)計(jì)方法與表3數(shù)據(jù)統(tǒng)計(jì)方法一致,并計(jì)算了各個(gè)版本以無優(yōu)化HIP版本為基準(zhǔn)的加速比。為進(jìn)行對(duì)比,表5中也加入了表3中CPU和OpenCL程序的運(yùn)行時(shí)間。可見經(jīng)過優(yōu)化之后,HIP版本性能已經(jīng)超過原版CPU和OpenCL版本的。
為驗(yàn)證優(yōu)化的通用性,本文還對(duì)另外2個(gè)典型算例——Lysozyme[11]和waterbox[12]進(jìn)行了性能對(duì)比測(cè)試。Lysozyme是對(duì)水盒子中的溶菌酶蛋白質(zhì)的模擬,體系原子數(shù)為71 844,相對(duì)[C16MP]+[Br3]-,其成鍵力計(jì)算要少得多。waterbox是僅包含溶劑水分子的體系,本文使用的是包含64萬個(gè)水分子、共192 000個(gè)原子的體系,規(guī)模較大,但是成鍵力全部以“約束”(constraint)的方式在CPU上計(jì)算。表6列出了Lysozyme和waterbox算例的運(yùn)行性能數(shù)據(jù),可見優(yōu)化的HIP版本相對(duì)優(yōu)化之前以及原版的CPU和OpenCL版本均有一定的性能提升。
Table 5 Performance comparison among different optimization methods表5 不同優(yōu)化方法性能對(duì)比
Table 6 Performance comparison among different GROMACS versions with Lysozyme and waterbox benchmarks表6 算例Lysozyme和waterbox在不同版本GROMACS下的性能對(duì)比
進(jìn)一步對(duì)比這2個(gè)算例的性能數(shù)據(jù),運(yùn)行Lysozyme算例時(shí)OpenCL版比CPU版的性能高71.6%,而運(yùn)行waterbox算例時(shí)OpenCL版比CPU版的性能高97.4%,可見GROMACS作為一個(gè)通用MD模擬軟件,支持的模擬種類眾多,由于不同類型的算例實(shí)際運(yùn)行的代碼不同,即使是官方原版,計(jì)算不同算例的相對(duì)性能也有差異。本文以[C16MP]+[Br3]-這一算例為目標(biāo)進(jìn)行的一系列優(yōu)化,對(duì)Lysozyme和waterbox算例也有一定加速效果,證明了優(yōu)化措施的通用性;但另一方面,在Lysozyme和waterbox算例上的加速效果不如[C16MP]+[Br3]-,這也體現(xiàn)了通用代碼的復(fù)雜性。若要獲得最佳的性能,則需要對(duì)目標(biāo)算例進(jìn)行針對(duì)性的分析與優(yōu)化。
為了從更多角度測(cè)評(píng)優(yōu)化效果,本文還使用優(yōu)化前后的HIP代碼分別進(jìn)行了擴(kuò)展性測(cè)試,包括弱擴(kuò)展性測(cè)試和強(qiáng)擴(kuò)展性測(cè)試。由于PME算法本身在計(jì)算過程中要求全局通信,因此GROMACS 2020版本只支持單GPU卡計(jì)算PME,即使使用多結(jié)點(diǎn)運(yùn)行,也只能指定使用一個(gè)進(jìn)程單獨(dú)計(jì)算PME,通常這會(huì)對(duì)程序的擴(kuò)展性造成不利影響。使用CPU計(jì)算PME則沒有這一限制,因此,在擴(kuò)展性測(cè)試部分,各個(gè)規(guī)模下均使用CPU計(jì)算PME,bonded和nb部分仍然使用GPU進(jìn)行計(jì)算。
弱擴(kuò)展性測(cè)試將[C16MP]+[Br3]-這一算例規(guī)模分別擴(kuò)展為原來的1倍、2倍、4倍和8倍,分別使用1,2,4和8個(gè)結(jié)點(diǎn)進(jìn)行計(jì)算。強(qiáng)擴(kuò)展性測(cè)試則將[C16MP]+[Br3]-這一算例擴(kuò)展為原來的8倍,分別使用1,2,4和8個(gè)結(jié)點(diǎn)進(jìn)行計(jì)算。擴(kuò)展性測(cè)試中時(shí)間統(tǒng)計(jì)方法與表3數(shù)據(jù)統(tǒng)計(jì)方法一致,結(jié)果分別列于表7和表8。
Table 7 Test results of weak scalability 表7 弱擴(kuò)展性測(cè)試結(jié)果
Table 8 Test results of strong scalability 表8 強(qiáng)擴(kuò)展性測(cè)試結(jié)果
由于PME部分采用CPU計(jì)算,所以損失了該部分的優(yōu)化效果,但在2種擴(kuò)展性測(cè)試中,各個(gè)測(cè)試規(guī)模下優(yōu)化后的HIP版本均比優(yōu)化前有明顯的性能提升。同時(shí)也可以發(fā)現(xiàn),優(yōu)化后相比優(yōu)化前的加速比不及單結(jié)點(diǎn)時(shí)的情況。其主要原因是該算例PME部分計(jì)算量較多,使用CPU計(jì)算PME時(shí)該部分運(yùn)行時(shí)間在總時(shí)間中占比始終過半,同時(shí)隨著結(jié)點(diǎn)數(shù)和算例規(guī)模的增加,PME部分通信量也迅速增加,對(duì)性能的制約更加嚴(yán)重,因此優(yōu)化效果逐漸降低。
圖7a和圖7b分別展示了弱擴(kuò)展性和強(qiáng)擴(kuò)展性測(cè)試中不同規(guī)模下優(yōu)化前后算例運(yùn)行總時(shí)間和PME時(shí)間,可見優(yōu)化前后,隨著結(jié)點(diǎn)數(shù)的增長(zhǎng),PME部分時(shí)間占比都是增長(zhǎng)趨勢(shì),且優(yōu)化后,各個(gè)規(guī)模下PME時(shí)間占比都超過65%,說明PME以外的部分都得到了較好的優(yōu)化。
Figure 7 Percentage of PME time in scalability tests 圖7 擴(kuò)展性測(cè)試PME時(shí)間占比
擴(kuò)展性測(cè)試的結(jié)果表明,盡管本文并未針對(duì)GROMACS的通信以及計(jì)算流程等方面進(jìn)行優(yōu)化,但通過對(duì)GPU核函數(shù)的優(yōu)化,在多結(jié)點(diǎn)計(jì)算時(shí)相對(duì)優(yōu)化前仍取得了可觀的性能提升。另一方面,該組測(cè)試也體現(xiàn)了PME部分對(duì)擴(kuò)展性的限制,為后續(xù)針對(duì)多結(jié)點(diǎn)、大規(guī)模計(jì)算的優(yōu)化指明了方向。
本文通過將廣泛使用的分子動(dòng)力學(xué)模擬軟件GROMACS 2020系列轉(zhuǎn)碼為HIP代碼,實(shí)現(xiàn)了其功能在ROCm上的完整移植。進(jìn)一步以一個(gè)復(fù)雜的離子液體模擬算例為目標(biāo),對(duì)其主要GPU核函數(shù)進(jìn)行了逐一優(yōu)化,實(shí)現(xiàn)了相對(duì)初始轉(zhuǎn)碼版本約2.8倍的加速比。優(yōu)化后的版本在MI50 GPU上的性能高于GROMACS原版OpenCL代碼60.5%,相對(duì)運(yùn)行在EPYC 7502 處理器的原版CPU代碼的加速比約為2.7。此外,本文還在另外2個(gè)典型算例Lysozyme和waterbox上進(jìn)行了測(cè)試。結(jié)果顯示,優(yōu)化后的HIP版本相對(duì)原版CPU和OpenCL版本均有一定的性能加速。通過對(duì)所用離子液體算例的擴(kuò)展,分別測(cè)試了優(yōu)化前后HIP版本代碼的強(qiáng)弱擴(kuò)展性,一方面說明針對(duì)單結(jié)點(diǎn)的優(yōu)化在多結(jié)點(diǎn)運(yùn)行時(shí)仍然體現(xiàn)了良好的加速效果,另一方面也發(fā)現(xiàn)了PME部分對(duì)擴(kuò)展性提升的制約,為后續(xù)針對(duì)大規(guī)模體系的優(yōu)化提供了方向。本文的工作豐富了GROMACS可使用的軟硬件平臺(tái),所采用的移植方法、優(yōu)化思路及方法對(duì)于其他GPU應(yīng)用的移植和優(yōu)化也有一定借鑒意義。未來我們將就更大規(guī)模的可擴(kuò)展性優(yōu)化展開研究。