【鯤鵬經典直播征文】+【畢昇編譯器】編譯優化與軟硬協同釋放鯤鵬澎湃算力
一、背景知識——編譯優化與軟硬協同
編譯器:將源程序(高級語言)轉換為等價的機器語言
源代碼(source code)→預處理器(preprocessor)→編譯器(compiler)→目標代碼(object code)→鏈接器(Linker)→可執行程序(executables)
編譯優化:保留程序語義(正確性)的前提下,對程序進行等價變化,從而較少程序運行時間
軟硬協同:在編譯優化中適配/使能諸多硬件特性
HPC( High Performance Computing,高性能計算)領域主要是解決計算密集型、海量數據處理等業務的計算需求,如科學研究、氣象預報、計算模擬等。如何提高計算能力、極致化應用性能成為當前 HPC 領域各大平臺最關鍵的課題之一,編譯器在其中發揮著至關重要的作用。
二、認識畢昇編譯器
畢昇編譯器是基于開源LLVM 10.0.1版本開發,并進行了優化和改進,同時將flang作為默認的Fortran語言前端編譯器,是一種Linux下針對鯤鵬920的高性能編譯器,其針對鯤鵬平臺進行了深度優化的高性能編譯器。除支持 LLVM 通用功能和優化外之外,對中端及后端的關鍵技術點進行了深度優化,對以下三個方面進行了增強,使得鯤鵬平臺的強勁算力能夠最大限度地得到釋放。
高性能編譯算法:編譯深度優化,內存優化增強,自動矢量化等,大幅提升指令和數據呑吐量。
加速指令集:結合 NEON/SVE 等內嵌指令技術,深度優化指令編譯和運行時庫,發揮鯤鵬架構極致算力。
AI 迭代調優:內置 AI 自學習模型,自動優化編譯配置,迭代提升程序性能,完成最優編譯。
關鍵特性
支持鯤鵬微架構芯片及指令優化
通過軟硬協同提供相較開源LLVM更高的性能
集成Auto-tuner特性支持編譯器自動調優
運行平臺:鯤鵬920硬件平臺
操作系統:openEuler21.03、openEuler 20.03 (LTS)、CentOS 7.6、Ubuntu 18.04、Ubuntu 20、麒麟V10、UOS 20
注:詳細的運行平臺和操作系統對應關系請參見?兼容性查詢工具
部分通用信息請參考LLVM的用戶指導https://llvm.org/docs/UserGuides.html
相比GCC和icc,LLVM前端Clang對語法的檢查更嚴謹,嚴格匹配語言標準,Clang的常見兼容性和可移植性問題,請參考開源官方文檔https://clang.llvm.org/compatibility.html
支持的編程語言
LLVM是一種涵蓋多種編程語言和目標處理器的編譯器,畢昇編譯器聚焦于對C、C++、Fortran語言的支持,利用LLVM的Clang作為C和C++的編譯和驅動程序,Flang作為Fortran語言的編譯和驅動程序。
1、C,C++程序
Clang不僅僅是可以將C, C++程序編譯為LLVM中間表示的IR,它也是一個驅動程序,會調用所有以代碼生成為目標的LLVM優化遍,直到生成最終的二進制文件。畢昇編譯器提供了端到端編譯程序所需的所有工具和庫。
2、Fortran程序
Flang是專為LLVM集成而設計的Fortran前端,由兩個組件flang1和flang2組成。它也是一個驅動程序,將源代碼轉換為LLVM IR,前端驅動程序將IR傳輸下去進行優化和目標代碼生成。
畢昇編譯器優化效果:Benchmark跑分、HPC典型應用性能提升
當前畢昇編譯器已廣泛應用于多種 HPC 典型場景,如氣象、安防、流體力學等,性能優勢已初步體現。畢昇編譯器與鯤鵬芯片協同,充分發揮芯片的性能,提升鯤鵬硬件平臺上業務的性能體驗。
基于鯤鵬上編譯器優化,SPEC CPU 2017 benchmark 跑分平均優于 GCC 20%以上
HPC 典型氣象應用 WRF 優于 GCC 10%~20%
三、畢昇編譯器典型優化場景及其優化原理
1、結構體內存布局優化——大幅提升緩存命中率,突破訪存瓶頸
將結構體數組轉換為數組結構體
結構體可以是顯式的,也可以通過檢查循環中的數組使用情況來推斷它們
可見在 struct 中,data1 的使用率極高,而 data2 是不使用的。然而由于源代碼中,數據的排布是以結構體數組的形式排布。按照一般編譯器的編譯方式,拿數據時每次都會將整個結構體放到 cache 里面,導致大量不參與計算的 data2 也被加載到了 cache 中,造成高速內存空間的浪費和性能的損耗。畢昇編譯器會通過用戶標記的結構體聲明,或者通過自動檢查循環中適合優化的內存場景,確認優化點。然后通過將結構體數組變為數組結構體的方式(如上圖右),將有效數據緊湊排布,從而提高 cache 命中率和應用性能。經測試,此優化可以對 mcf 子項帶來50%的性能提升。
2、結構體指針壓縮優化——大幅降低內存使用,提升緩存命中率
使編譯過程更加靈活和可控
細粒度編譯控制,提供更多優化機會
將指針成員由8字節壓縮至4字節,減小每個結構體node的內存體積。被壓縮的域成員指針外提為全局結構體指針ps_head,ps變換為相對基址的偏移,將有效數據緊湊排布,從而大幅降低內存使用,提升 cache 命中率和應用性能。
3、軟件預取——大幅提高程序性能,提升緩存命中率
(1)軟件預取:通過插入預取指令提前從內存中讀取所需數據
(2)預取的效果取決于“提前量”
數據太早到達→浪費寶貴的cache空間
數據太晚到達→仍需要等待訪存過程
(3)如何計算“提前量"
循環大小
Cache line大小
訪存延遲
(4)針對鯤鵬微架構特征調整軟件預取參數
4、自動矢量化—計算效率提升的秘訣
使用矢量寄存器、矢量指令提高并行度
理論基礎:SIMD(single instruction multiple data),一條指令可以處理多個數據
硬件基礎:ARM NEON指令集擴展,32個128位的矢量寄存器,指令可以同時操作4*32或2*64的數據
軟件基礎:編譯器針對NEON指令的分析和優化
鯤鵬平臺支持 Armv8 NEON 矢量化指令集。當前支持32個128位的矢量寄存器,指令可以同時操作4*32或2*64的數據。畢昇編譯器依托這種硬件優勢做了大量優化,包括 SLP(superword-level parallelism) 矢量化和循環自動矢量化。
例如在 SPEC CPU 2017 benchmark 中處理視頻流格式轉換的x264子項中,畢昇編譯器會自動識別并使用 uabd 和 udot 這類高效向量指令完成計算來替換標量指令,增大單時鐘周期的數據處理量, 從而大幅提升計算效率。對于 x264 子項,這項優化可有效提升其30%的計算效率。
5、循環優化——幫助發現更多的優化機會
Loop unroll:將循環體復制多遍
減少分支跳轉次數
幫助發現更多的優化機會
Loop (partial) unswitch:外提(減少)循化內條件判斷
Loop fusion/distribution:將循環體合成一個/拆成多個
6、Autotuner—基于機器學習快速獲取最優編譯配置
如何獲取性能最優編譯選項是編譯器使用中常見的問題,往往需要長時間的手動選項調優。為了減少這其中的工作量,使得用戶能快速找到最優的優化選項,畢昇編譯器自研了基于 ML 的自動搜索技術(ML-based Search) 的 Autotuner 工具。
一種自動化的迭代過程, 通過操作編譯設置來優化給定程序,以實現最佳性能。它由兩個組件配合完成,畢異編譯器和Autotuner命令行工具。此功能不需要在源代碼中注入pragma,而是允許用戶在簡單的yaml文件中指定優化配置,該文件包含優化信息及其相應的代碼區域信息,包括名稱和行號。此外,它還可以記錄優化結果,以及可調優的代碼區間并以yaml的形式導出。
與畢昇編譯器進行交互:
根據編譯器產生的可調優代碼結構創建搜索空間(search space)
生成編譯配置并調用編譯器來編譯源代碼
操作調優參數以及應用搜索算法
自帶的遺傳算法
獲取性能數據
引入基于ML的自動搜索技術(ML-basedSearch)
關鍵技術點:
1、知識庫(Autotuner Database):根據靜動態分析信息,建立知識庫,支持決策系統進行優化
2、優化決策系統(Optimal configuration):根據熱點和性能評估信息、知識庫信息,綜合考慮確定優化措施
3、熱點標記和性能評價:熱點標記,瓶頸檢測,性能評估
4、查找驅動(Feedback):將優化決策系統,反饋的優化建議
Autotuner 的調優流程由兩個階段組成:初始編譯階段(initial compilation)和調優階段(tuning process),如下圖所示:
初始編譯階段
初始編譯階段發生在調優開始之前,Autotuner首先會讓編譯器對目標程序代碼做一次編譯,在編譯的過程中,畢昇編譯器會生成一些包含所有可調優結構的YAML文件, 告訴我們在這個目標程序中哪些結構可以用來調優,比如文件(module), 函數(function), 循環(loop)。 例如,循環展開是編譯器中最常見的優化方法之一,它通過多次復制循環體代碼,達到增大指令調度的空間,減少循環分支指令的開銷等優化效果。若以循環展開次數(unroll factor)為對象進行調優,編譯器會在YAML文件中生成所有可被循環展開的循環作為可調優結構。
調優階段
當可調優結構順利生成之后,調優階段便會開始:
Autotuner首先讀取生成好的可調優結構的YAML 文件,從而產生對應的搜索空間,也就是生成針對每個可調優代碼結構的具體的參數和范圍;
調優階段會根據設定的搜索算法嘗試一組參數的值,生成一個YAML格式的編譯配置文件(compilation config),從而讓編譯器編譯目標程序代碼產生二進制文件;
最后Autotuner將編譯好的文件以用戶定義的方式運行并取得性能信息作為反饋;
經過一定數量的迭代之后,Autotuner將找出最終的最優配置,生成最優編譯配置文件,以YAML的形式儲存。
簡單來說,在初始編譯階段,編譯器會通過用戶指定的調優方向,對可調優的代碼區間進行標記。在隨后的調優階段,Autotuner 會根據搜索算法對不同的優化區間生成不同的編譯配置。然后使用此配置編譯運行,并根據運行性能的反饋來迭代優化配置參數。最后經過給定迭代次數后找出最優配置供用戶使用。在實踐過程中,通過 Autotuner 對 Coremark Benchmark 進行調優可以獲取5%以上的收益。
7、畢昇編譯器Fortran前端:特性、架構與優化增強
(1)畢昇編譯器Fortran語言前端基于Classic Flang構建,通過增強Classic Flang,支持如下特性:
支持F2003、F2008 (Coarray特性除外)語言標準
最高支持四倍浮點精度(real16)數據類型,15維數組數據類型,支持OpenMP4.0、OpenMP4.5并行化編程模型
支持DWARF4標準
多種Pragma引導語支持,如軟件prefetch,omp simd,unroll,vector等
(2)多個Fortran內建函數的優化
maxloc/minloc/nint的內聯
trim/lentrim采用更優算法
(3)內存分配優化,棧內存替挽堆內存
(4)為中后端提供更準確詳細的信息來輔助優化
別名分析增強
過程間優化增強
四、畢昇編譯器:新版本
1、畢昇編譯器1.3.3版本已于2021.06.30正式發布,點擊”畢昇編譯器軟件包下載”,下載后解壓使用:畢昇編譯器軟件包下載
其中包含以下新特性:
支持基于Structure Peeling的特性增強及指針壓縮優化
完善Fortran2003/2008語言特性
新增大量優化特性:支持unroll and jam,loop distribution優化增強,軟件預取增強,靜態分支優化改善,循環矢量化特性增強等
Autotuner特性增強與完善,改善調優時間
新增支持macOS 10.0及以上版本
支持申請并使用鯤鵬遠程云調測環境
優化操作易用性
新增畢昇JDK安裝部署功能
修復部分已知BUG
2、軟件包下載
點擊”畢昇編譯器軟件包下載”,下載后解壓使用:畢昇編譯器軟件包下載
點擊”畢昇編譯器sha256”,用于對比完整性校驗結果:畢昇編譯器 sha256
3、參考文檔
畢昇編譯器用戶指南
畢昇編譯器Autotuner 特性指南
4、問題討論
鯤鵬社區論壇,可發帖提問:https://bbs.huaweicloud.com/forum/forum-923-1.html
五、總結
針對不同的場景,不同的應用特點,使用不同的編譯優化手段
編譯優化的代價與收益權衡,需要綜合考慮性能收益,代碼體積,編譯時間,可調試性等多方面因素
軟硬件結合,通過軟件及硬件的協同優化,最大化的發揮硬件算力
語言生態構建的持續性,語言標準的不斷演進,及新特性支持
【參考】
【1】鯤鵬論壇編譯器版塊:https://bbs.huaweicloud.com/forum/forumdisplay-fid-928-orderby-lastpost-filter-typeid-typeid-1642.html
【2】鯤鵬開發套件:https://kunpeng.huawei.com/#/developer/devkit/
【3】鯤鵬首頁:https://kunpeng.huawei.com
【4】【畢昇編譯器】編譯優化與軟硬協同釋放鯤鵬澎湃算力:https://bbs.huaweicloud.com/live/kunpeng_live/202105311500.html
ARM 高性能計算 鯤鵬
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。