ARM 的崛起構築了終端市場的繁榮,也終結了 x86 過去 40 餘年一家獨大的局面。隨着 ARM 構架開始更多的向 x86 設備中滲透,越來越多的服務也轉向了 ARM 雲平臺。華爲公司作爲 ARM 服務器市場的先行者,其自研的鯤鵬系列 ARM 處理器,性能處於 ARM 平臺服務器 CPU 的第一梯隊。秉持着“硬件開放、軟件開源、使能夥伴”的初心,鯤鵬產業生態正在賦能更多的行業,也吸引了成千上萬開發者的關注和參與,優秀的開源項目和應用實踐不斷湧現。

憑藉自身雄厚的技術實力和研發經驗,華爲聯合各地鯤鵬生態創新中心在全國範圍內開啓了鯤鵬應用創新大賽 2020,本次大賽設置有十三大賽區,廣州賽區便是其中之一。7 月 25 日,廣州鯤鵬生態創新中心以線上直播方式舉辦的【鯤鵬應用創新大賽 2020·廣州賽區宣講會】成功召開。本次活動不僅邀請到了華爲鯤鵬資深技術專家爲開發者全方位講解鯤鵬軟件遷移和性能調優技術,還在線解答了關於本次大賽的相關問題,幫助開發者更多瞭解到廣州賽區的賽事詳情。

以下內容經由 InfoQ 編輯整理自鯤鵬創新應用大賽 2020 廣州賽區宣講會速記。

爲什麼要進行軟件遷移、怎麼遷移?

x86 和華爲鯤鵬 ARM 架構之間最大的區別源自於指令集的不同。以下圖的 C/C++ 程序代碼中的“c=a+b”語句爲例,我們可以看到其通過編譯器編譯彙編指令後,指令集存在以下三點差異:

1、彙編不同:語句在 x86 平臺下生成一個彙編指令後,通過 3 條 mov 指令和 1 條 add 指令完成執行;而鯤鵬處理器則是通過 ldr 指令將數據加載到計算器當中,再通過 add 指令將兩個計算器裏面的數據進行相加,最後通再過一條 Str 指令將計算器中的內容存儲在內存當中。

2、指令長度不同:x86 上 mov 指令是 24 位的,ldr 指令是 16 位的;而鯤鵬處理器的指令是定長的 32 位指令。

3、寄存器不同:x86 和鯤鵬處理器使用的向量寄存器不同,其向量指令級也存在差異。

基於上述的指令集差異,因此基於 x86 平臺編譯生成的應用程序,在鯤鵬處理器平臺上進行運行的時候,需要進行重新的編譯。

那麼,從 x86 到鯤鵬的軟件遷移如何操作?鯤鵬在長期的項目遷移過程中總結了五大步驟:

1、遷移準備——收集硬件和軟件棧信息,並準備編譯環境。包括以芯片、服務器信息爲主的硬件信息和中間件、編譯器、業務軟件、開源軟件和商業軟件等爲主的軟件棧信息。同時,進行編譯環境的準備,可以通過申請 OpenLab 的軟件幫助我們完成遷移。

2、遷移分析——分析軟件棧制定遷移策略。軟件技術棧分析主要分爲業務軟件分析和運行環境分析兩大類。在業務軟件中,開源軟件可通過獲取開源軟件代碼進行程序編譯,或直接下載 ARM 上已編譯好的軟件包;自研軟件則需根據語言類型差異制定不同的遷移策略;商用軟件是鯤鵬處理器常用版本,當無法獲取相應商用軟件版本時,可通過其他軟件或開源軟件進行替換。運行環境、虛擬機、編譯器和操作系統這些也是要進行替換,可以直接去軟件倉庫下載由鯤鵬官方驗證的版本。

3、編譯遷移——軟件編譯打包,驗證基本功能。主要分爲代碼遷移和軟件包遷移,代碼遷移的過程中需要區分編譯型語言和解釋型語言;軟件包遷移的核心在於 RPM 包的重構,包括掃描軟件包的依賴項,對這些依賴庫進行重新編譯打包。

4、性能調優——完成遷移之後需要進行性能調優。這裏總結出性能調優的五步法:首先是建立基準。根據當前硬件配置和測試模型,確定調優的目標。第二,壓力測試。對測試系統進行壓力測試,記錄數據變化。第三,確定瓶頸。系統的瓶頸通常會在 CPU 過於繁忙、IO 等待、網絡等待、響應時延等方面出現。第四,實施優化。重點觀察系統資源的瓶頸,對瓶頸點實施進一步調優策略。第五,確認效果。重新啓動壓力測試,準備好相關的工具監視系統,確認優化效果。

5、測試與認證。對軟件進行功能測試、性能測試、長穩測試,以確保達到鯤鵬規模商用的標準。

C/C++ 等編譯型語言如何遷移?

C/C++ 作爲典型的編譯型語言,由於架構、指令集、向量寄存器的差異,程序在從 x86→鯤鵬處理器時,必須經過重新編譯才能運行。

從代碼工程的角度來看,C/C++ 的文件分爲兩類,一是編譯構建的腳本,二是源碼。其中:

1、編譯構建腳本類文件在遷移過程中一般會涉及編譯選項的移植,包括指定數據類型、生成代碼特性、目標執行器架構、處理器硬件加速功能等。

2、源碼文件的遷移,一般會涉及到編譯宏的移植、編譯器自帶 builtin 函數移植、內聯彙編移植、SSE intrinsic 函數移植等。

下圖展示了 C/C++ 代碼完整的編譯構建過程。首先通過 GitHub 和第三方開源社區獲取相應的源碼。其次安裝 gcc 版本,準備編譯環境。之後使用源碼中的 CMakeLists.txt 或 configure 腳本生成 makefile。隨後執行 makefile 編譯可執行程序,並替換依賴庫。最後,將可執行程序安裝部署到生產或測試系統。

不過,C/C++ 代碼在遷移中也會有諸多問題存在,最具代表性的五類遷移問題如下:

1、編譯腳本和編譯選項的移植。不同的架構平臺會有獨特的編譯選項支持硬件特性,與當前編譯平臺屬性強相關這種帶有架構屬性的編譯選項需要進行移植,這些編譯選項一般以–m 開頭;

2、編譯宏的移植。編譯宏的作用是確定平臺下需要執行哪個分支代碼,一般分爲 x86 自定義宏和用戶自定義的宏。兩類宏的編譯移植方式各不相同;

3、builtin 函數問題。builtin 函數是編譯器自定義的函數,有較好的性能,可以實現一些簡單快捷的功能,根據相應需求進行使用優化,助力程序編寫;

4、內聯彙編移植,常用遷移方法有彙編指令方式替換以及 builtin 函數替換兩種;

5、SSE intrinsic 函數移植。一般在多媒體技術開發以及數學矩陣庫中應用較多的 SSE intrinsic 函數移植較爲複雜,爲重難點。

Java/Python 等解釋型語言怎麼遷移?

Java 源碼遷移的改動點一般有三個。第一是安裝 JDK 改動點,第二是引用 SO 庫的改動點,第三是程序運行時的改動點。

安裝 JDK 改動點遷移方法

Java 源碼移植過程首先需要安裝合適的 JDK 版本。基於對環境穩定性等要求,最好安裝一個穩定成熟高版本 JDK。因爲一般新版本的 JDK 往往會增加一些特性使其變的更加方便和敏捷。目前鯤鵬上已經適配了 EDM 八版本的 JDK,不過,如果因爲特殊的需求,需要安裝某個特定版本的 JDK,則需要通過源碼編譯部署來實現。

那麼,源碼編譯部署一個 JDK 應該如何來實現呢?首先需要安裝一個 GCC,其次獲取 JDK 源碼,獲取源碼之後我們需要配置編譯選項。例如配置語言選項、設置目標平臺位數、忽略警告、調試等級等等。在完成編譯選項後,可以執行 make all 進行編譯。編譯完成之後可以得到二級指文件,這個時候涉及環境變量進行驗證,通過驗證可以看到是不是我們想要的 Java 版本。

包含 SO 庫調用的 jar 包遷移方法

首先通過 Dependency Advisor 工具分析掃描 jar 包,識別依賴 SO 庫,並下載 SO 庫源碼。隨後安裝 maven、gcc,並設置參數。最後編譯 SO 庫和替換 SO 庫,並重新打包 jar 文件,這樣得到的 jar 包就可以在鯤鵬平臺上運行。

設置 JVM 參數解決程序運行時改動點。

設置 JVM 參數可以保證程序能穩定、快速的運行。這裏提供三大遷移經驗和兩大差異。

三大經驗:首先,完成一次 Full GC 後,應該釋放出 70% 的堆空間(30% 的空間仍然佔用)。其次,假設老年代存活對象 (即 Full GC 後老年代內存佔用) 大小爲 X,建議堆的總大小是 X 的三到四倍,年輕代的大小是 X 的 1 到 1.5 倍,老年代的大小是 X 的兩到三倍,永久代的大小是 X 的 1.2 到 1.5 倍。第三,JDK 官方的建議是年輕代大小佔整個堆空間大小的 3/8 左右。

在具體的項目過程中,還會存在兩大差異:第一,線程大小的 Xss 參數在 ARM 上默認值是 2m,在 x86 爲 1m。因此如果線程開的太多,就需要調整 xss 參數大小,防止出現耗時。第二,由於 ARM 和 x86 指令集的差異性,導致 JDK 的 JIT 編譯存在差異。可以通過設置參數 ReservedCodeCacheSize,調整 CodeCache 大小。

那麼,Python 代碼如何進行遷移呢?我們從 Python 源碼遷移的改動點來看,分別是 Python 的版本改動點和引用 SO 庫的改動。

升級 Python 版本

目前 Python2X 版本官方已經停止維護了,因此建議把環境升級至 Python3X。首先,安裝 GCC,配置編譯選項 fsigned-char。隨後在官方網站下載源碼包並解壓,配置編譯選項。隨後生成一個 Makeall 的文件,進行編譯和安裝。安裝完成之後會在設定的安裝目錄得到 Python3 的二級指文件,可以看到 Python 顯示版本號已經是我們想要的版本了,說明 Python 環境安裝已經成功。

含 C 模塊或全 C 模塊的遷移

含 C 模塊或全 C 模塊的遷移,其核心是調用了 SO 庫,對於 SO 庫我們需要重新編譯得到 aar64 的版本。首先,通過 Porting Advisoe 工具分析源碼,識別依賴 SO 庫和 C 代碼。隨後下載模塊源碼、安裝 GCC 並配置 -fsigned-char 選項。之後執行 setup 自動完成模塊編譯。編譯完成之後,自動會完成 aacrh64 版本庫的替換,然後我們將編譯完成得到的模塊安裝到 site—packages 目錄下,供其他 Python 源碼調用。

軟件調優怎麼做?

軟件性能調優是開發中最重要的活動,也是軟件工程中的深水區。往往軟件越是龐大挑戰程度越高,所需要考慮的問題也需要更全面。而從 4800×4800 矩陣乘法加速效果實測的結果來看,軟硬協同將帶來萬倍代碼性能提升。這就是我們爲什麼一定要做性能調優的原因。

從馮諾伊曼架構來看,影響性能的硬件因素主要有 CPU、內存、網卡和磁盤,因此這些硬件之上的應用是否合理對性能的影響極爲關鍵,也是調優性能的主要方向。

CPU 和內存

CPU 和內存優化的兩大方向分別是軟加速和硬加速,軟加速主要涉及編譯優化、NUMA-Aware 親和性優化。編譯器優化主要是針對鯤鵬芯片的微架構,優化了寄存器的分配、指令的部署和流水,提升大部分指令的執行效率。具體來講,主要分爲佈局優化、內存佈局優化、以及循環優化等;NUMA-Aware 主要是減少內存的跨片和跨 NUMA 訪問時產生時延,提高多核架構下面的並行度。此外,硬件加速則是鯤鵬處理器爲性能提升提供的一個核武器。

磁盤

因爲內存和 CPU 的高速緩存大小都是有限的,我們需要訪問的數據大多存在磁盤上或者網絡存儲上。因此文件系統決定了磁盤加載到內存過程的快慢。華爲鯤鵬提供了 EX3、EX14、以及 XFS 等數據訪問的管理模式,能夠有效提高訪問磁盤的性能。

網卡

主要需要根據實際應用場景來調整 frames 和 usecs 兩個特性,根據延時和帶寬需求來權衡控制兩個參數。

應用層

開發者可以提高併發數、優化緩存操作、啓用異步讀寫等,針對鯤鵬平臺的系統特性進行整體配置。

在具體的性能調優實踐中,第一步就是選擇調優方向,包括三大塊硬件和應用;第二步是性能採集、分析性能瓶頸、定位熱點函數;第三步是針對平臺特性充分利用硬件資源;第四步是要在網絡端尋求合適的參數平衡點。

鯤鵬應用創新大賽 2020·廣州賽區

爲了貫徹落實鯤鵬產業生態建設,更好的培育大灣區鯤鵬產業生態,並深入實施信息技術創新戰略,廣州“鯤鵬 + 昇騰”生態創新中心現計劃舉辦首屆“鯤鵬凌粵,展翅灣區”鯤鵬應用創新賽。此次活動以企業開發者爲主體,組織鯤鵬賦能培訓,並輔以大賽進行成果檢驗,訓賽結合,以訓促賽,推進廣東地區鯤鵬生態環境的健康發展,提升地區競爭力。

廣州賽區共設有“金融”、“政府”、“大數據”、“ARM 原生應用”和“開放命題”5 個賽題,主要面向企業參賽者,廣州賽區的獎項激勵總額可達 54 萬元。各賽題優勝隊伍(一等獎)將推選參加“華爲開發者大賽 @鯤鵬應用創新大賽 2020”全國賽,全國賽決賽每個賽題將選出 1 支金獎隊伍和 2 支銀獎隊伍。

參賽隊伍要取得好成績,需要注意以下幾點:

1、選好作品,解決方案應該足夠成熟、應用廣泛、有鮮明特色;

2、軟件適配鯤鵬平臺時要改造徹底,並根據鯤鵬架構做針對性改進和創新;

3、需要準備完整的測試報告,展示報告中要清晰展示方案的架構、功能、價值、前景和優勢等要素。

目前,本次比賽的報名渠道已經全面開放,所有的有意參賽者均可在 8 月 15 日前報名並提交作品,點擊 鏈接 可以瞭解到更多參賽信息,報名通道也由此進入。

本次【鯤鵬應用創新大賽 2020·廣州賽區宣講會】成功舉辦,不僅爲開發者打造了一個學習軟件遷移和調優經驗的平臺,同時也同步了本次大賽的更多賽事詳情,開發者可以通過參與大賽提升實踐技能、贏取豐厚大獎。在鯤鵬持續使能開發者、使能合作伙伴的初心下,可以預見,隨着鯤鵬產業生態的同行者和共建者越來越多,鯤鵬計算體系生態圈的進一步擴大。

相關文章