用NVIDIA NsightcComputeRoofline分析加速高性能HPC的应用
用NVIDIA NsightcComputeRoofline分析加速高性能HPC的應用
編寫高性能的軟件不是一件簡單的任務。當有了可以編譯和運行的代碼之后,當您嘗試并理解它在可用硬件上的執行情況時,將引入一個新的挑戰。不同的平臺,無論是cpu、gpu還是其他平臺,都會有不同的硬件限制,比如可用內存帶寬和理論計算限制。Roofline性能模型幫助您了解應用程序使用可用硬件資源的情況,以及哪些資源可能會限制應用程序的性能。在勞倫斯伯克利國家實驗室,國家能源研究科學計算中心(NERSC)和計算研究部(CRD)一直在使用該模型來分析和優化NVIDIA gpu上運行的HPC代碼。
傳統的Roofline模型依賴于兩個特征來描述工作量:
算力:計算工作(FLOPs)和數據移動(字節)之間的比率
FLOP/s:每秒浮點運算
有了這些信息,可以在一個包含性能限制的Roofline和頂層的圖形上繪制一個內核,并將它們對內核的影響可視化。
Roofline模型是在伯克利實驗室發明的。一種用于收集NVIDIA GPU Roofline分析的相關性能數據的方法,該方法已經被原型化和驗證:
· Performance Analysis of GPU-Accelerated Applications using the Roofline Model
· Roofline Performance Modeling for
HPC and Deep Learning Applications
· Hierarchical Roofline Analysis for GPUs: Accelerating Performance Optimization for the NERSC‐9 Perlmutter System
基于Roofline模型的GPU加速應用性能分析
高性能HPC和深度學習應用的Roofline性能建模 gpu的分層Roofline分析:加速NERSC-9 Perlmutter系統的性能優化
鑒于Roofline分析在高性HPC中的普及,NVIDIA已經與伯克利實驗室合作,并將其集成到NVIDIA Nsight Compute中。隨著其2020.1版本的發布,Nsight Compute為HPC應用程序的Roofline分析提供了一種更為簡化的方式,并且更容易與Nsight Compute中的其他功能集成,以便進行性能分析。
Using Nsight Compute to collect roofline data
Nsight Compute是一個CUDA內核分析器,它提供詳細的性能度量和優化建議。現在,它還可以收集和顯示Roofline分析數據。要在報告中啟用Roofline圖,請確保在從GUI進行分析時選擇了GPU Speed of Light roofline Chart部分。提供的詳細或完整的集合包括此部分(圖1)。
Figure 1. Detailed section set in Nsight
Compute.
If you are profiling from the command-line, use the flag --set detailed or --set full.
You can also manually select individual sections with the --section flag. The name of this new section is SpeedOfLight_RooflineChart.
Understanding the application
在本文中,將使用一個基于BerkeleyGW代碼的小型應用程序。以獨立的方式實現該應用程序的關鍵科學工作負載之一。為了簡單起見,這個小應用程序抽象了部分BerkeleyGW代碼,只運行一個內核。可以在GitLab上找到這個小應用程序,以及更詳細的說明,提供試用。
Using roofline analysis step-by-step
GitLab存儲庫中使用了一些優化技術。為了演示NsightCompute中的所有功能(包括新添加的Roofline分析)如何相互補充以進行全面的性能分析,只討論其中的兩個步驟,步驟1和步驟3。
Baseline
在最初的串行CPU實現中,核心工作負載在三層嵌套的Fortran循環中表示:
do n1_loc = 1, ntband_dist ! O(1000)
do igp = 1, ngpown ! O(1000)
do ig = 1, ncouls ! O(10000)
注釋表示每個回路的行程計數的近似長度。選擇這種循環順序是為了以優化的模式訪問Fortran使用的列主內存布局的內存,因為代碼中的許多數組都是以ig作為第一個索引,igp或n1_loc作為第二個索引來訪問的。帶有OpenACC的初始并行端口是GitLab存儲庫中提供的基線代碼,如下所示,它折疊了三個循環,試圖利用GPU上的大規模并行硬件。結果如下所示:
!$ACC PARALLEL LOOP GANG VECTOR reduction(+:…)
collapse(3)
do n1_loc = 1, ntband_dist ! O(1000)
do igp = 1, ngpown ! O(1000)
do ig = 1, ncouls ! O(10000)
圖2中的初始roofline分析表明,內核的算術強度很低,足以低于圖表中的傾斜內存限制roofline。實現的運算強度為7.39 FLOP/byte,但V100雙精度機器平衡點的算術強度為7.5。在這一點上,做了足夠多的準備工作,使之成為計算界compute-bound。可能希望將算術強度增加到足以低于某個水平計算限制的上限。提供了一個更好的機會來最大化這個內核的計算性能。
Figure 2. Baseline roofline analysis chart.
roofline圖表還顯示了單精度浮點運算的數據點。編譯器會為這個內核生成一些這樣的代碼。它顯示單個精確Roofline的水平線,即兩條水平線中較高的一條。
Step 1: Unroll certain loops to gain arithmetic intensity
第三個循環的核心循環是連續運行的,這是第三個循環的循環。因為任何一對循環都會暴露至少一百萬個自由度,所以仍然應該有足夠的并行性來飽和高端GPU。要選擇哪一個,可注意代碼的內存訪問模式。對于所有多維數組,n1_loc在訪問之間的跨距最大,這也是由于column-major Fortran layout布局造成的。有效地使用GPU內存帶寬需要合并訪問,其中連續線程訪問內存中的連續位置。所以,這都意味著n1_loc循環是這個實驗最符合邏輯的目標。
!$ACC PARALLEL LOOP GANG VECTOR reduction(+:…)
collapse(2) do igp = 1, ngpown ! O(1000)
do ig = 1, ncouls ! O(10000)
!$ACC LOOP SEQ
do n1_loc = 1, ntband_dist ! O(1000)
當進行此更改時,內核實際上并沒有加速。事實上,運行時的速度下降了10%,從1.74秒降到了1.92秒,但是,現在已經確定了內核的計算極限,雙倍精度的算術強度大約為20當您進行此更改時,內核實際上并沒有加速。事實上,運行時的速度下降了10%,從1.74秒降到了1.92秒,但是,你現在已經確定了內核的計算極限,雙倍精度的算術強度大約為20浮點/字節(圖3)。圖4顯示了Nsight計算光速部分的內存利用率也低得多,基線(紅色)為34%,第1步優化后為11%(藍色)。這意味著,如果你能使計算更有效,你也許能更接近峰值(圖3)。圖4顯示了Nsight計算Speed of Light光速部分的內存利用率也低得多,基線(紅色)為34%,第1步優化后為11%(藍色)。這意味著,如果能使計算更有效,也許能更接近峰值。
Figure 3. Roofline chart after Step 1.
Figure 4. Comparison of SM and memory
utilization between baseline and step 1.
Step 3: Avoid high-latency instructions
高延遲指令可以顯著降低warp問題的發生率并降低計算并發性,特別是當沒有足夠的線程來隱藏延遲時。但是,可以應用某些技巧來用較低延遲的指令替換這些指令。這里,演示兩個,其中兩個復數的除法wtilde和wdiff替換為倒數,ssx和I_eps_數組的絕對值計算被指數計算代替,因為只用于if/else條件評估。
! before delw = wtilde / wdiff
! after wdiffr = wdiff * CONJG(wdiff)
rden = 1.0d0 / wdiffr delw = wtilde * CONJG(wdiff) *
rden
!before
ssxcutoff = sexcut *abs(I_eps_array(ig,igp))
if (abs(ssx) .gt. ssxcutoff .and. wx_array_t(iw,n1_loc).lt. 0.0d0) ssx=0.0d0 !
after
ssxcutoff = sexcut**2* I_eps_array(ig,igp) * CONJG(I_eps_array(ig,igp))
rden = ssx * CONJG(ssx)
if (rden .gt. ssxcutoff .and. wx_array_t(iw,n1_loc) .lt.
0.0d0) ssx=0.0d0
通過應用這些技巧,計算性能從2.5tflop/s提高到2.9tflop/s,代碼的運行速度提高了一倍。運算強度已經下降到6.3 FLOP/byte,使得GPP重新回到帶寬限制區域。這不是一個嚴重的問題,因為它在性能優化過程中經常發生。隨著計算并發性的增加,需要讀寫更多的數據來滿足計算需求。這可能會增加內存帶寬的使用,從而導致帶寬限制更大的Roofline圖。
Figure 5. Roofline chart of GPP before applying tricks in Step 3.
Figure 6. Roofline chart of GPP after Step 3.
NsightCompute中豐富的特征集是相輔相成的,這種優化的效果也可以通過其他度量來驗證。圖7和圖8顯示,由于將delw=wtilde/wdiffr替換為rden=1.0d0/wdiffr,sampled active warps(全部或未發出)的數量和狀態為wait(綠色條)的warp數量都顯著下降。第三步的abs trick技巧也有同樣的效果。
Figure 7. Change in sampling data after optimization transformations.
Figure 8. Another change in sampling data after optimization transformations.
Introducing hierarchical roofline analysis
到目前為止,文章展示了傳統的Roofline模型,它只為GPU DRAM內存使用一個內存Roofline。然而,內存子系統比這更復雜,可以擴展Roofline模型來合并GPU的L1和L2緩存。這種分層Roofline模型在前面鏈接的論文中有詳細描述。目前,Nsight Compute不支持分層Roofline模型,但它提供了一個可擴展的接口,允許創建自己的實現(圖9)。使用GitLab存儲庫中的SpeedOfLight_HierarchicalDoubleRooflineChart部分文件,可以為步驟3創建一個分層的Roofline圖表。
Figure 9. Hierarchical Roofline created with customized section files for Nsight Compute.
附加的對角線ceilings頂層表示給定算術強度的L1和L2性能限制。在這個圖中,每個圓表示內存子系統(L1、L2或DRAM)的不同級別,并使用來自該級別的流量來計算其算術強度。例如,紅點代表一級緩存,用內核的總浮點數除以一級緩存中移入和移出的字節數繪制。分層Roofline更詳細地說明內存層次結構的哪個級別可能是瓶頸。此信息允許調整內存布局或訪問模式以減少這些性能問題。
Summary
提高應用程序性能是一個迭代過程。了解內核所在的roofline圖表部分是指導后續開發工作的關鍵技能。例如,如果看到明顯地處于roofline圖表中內存帶寬受限的部分,那么最重要的事情就是內存訪問模式,這樣就可以避免浪費時間查看那些不會實質性地改變運行時的內核部分。此外,了解在每個迭代中的位置對于知道何時停止并繼續下一個工作項非常重要。Roofline分析,結合Nsight Compute提供的其他分析部分,可以幫助了解內核相對于可達到的峰值系統限制的性能,因此值得將此工具添加到工具箱中。
對于那些對更深入感興趣的人,文章只觸及了roofline分析所能達到的表面。NERSC網站上有更多關于Roofline模型的詳細信息,以及他們如何使用它來分析和提高性能。GitLab repo描述了另外兩個優化步驟,可以使用最新版本的Nsight
Compute進行實驗。
總結
以上是生活随笔為你收集整理的用NVIDIA NsightcComputeRoofline分析加速高性能HPC的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pipe Utilization管道利用
- 下一篇: 使用PCAST检测散度以比较GPU和CP