x86與ARM之爭(zhēng),已經(jīng)貫穿了很長(zhǎng)時(shí)間,過去一直是x86架構(gòu)比較受到市場(chǎng)和開發(fā)者的歡迎。但是自從移動(dòng)互聯(lián)網(wǎng)、物聯(lián)網(wǎng)和邊緣計(jì)算興起之后,ARM似乎已經(jīng)找到最適合自己生存的土壤。
架構(gòu)之爭(zhēng)的平臺(tái)技術(shù)拐點(diǎn),已然來臨。
現(xiàn)在,每個(gè)人手上都有一臺(tái)智能計(jì)算終端,移動(dòng)應(yīng)用逐漸云化,5G 催生了云游戲的誕生;Web 應(yīng)用的加密性越來越重要,HTTPS 流量越來越大;大數(shù)據(jù)分布式并行計(jì)算成為主流等,這些都讓 x86 架構(gòu)的不足逐漸顯露出來。
所以才會(huì)有現(xiàn)在所遇到的情況,即不得不從x86上的應(yīng)用遷移至ARM上。但也正因?yàn)檫@是兩個(gè)完全不同的平臺(tái),所以在遷移過程中會(huì)遇到各種各樣的問題。這也是DevRun 開發(fā)者沙龍–首期【鵬城實(shí)驗(yàn)室 & 華為鯤鵬專場(chǎng)】中所重點(diǎn)講到的問題之一。
以下內(nèi)容經(jīng)由InfoQ編輯整理自DevRun 開發(fā)者沙龍【鵬城實(shí)驗(yàn)室 & 華為鯤鵬專場(chǎng)】中張永正和楊少洪老師的分享。
鯤鵬軟件遷移概述和方法論
首先要搞懂:為什么要遷移?
上圖所示為程序執(zhí)行的過程和對(duì)應(yīng)的計(jì)算棧。任何一臺(tái)計(jì)算機(jī)都是由硬件和軟件組成的,類似于最底層的基礎(chǔ)物理原材料、晶體管、寄存器、微架構(gòu)等都屬于硬件層面。而軟件層面則特指由高級(jí)語言、匯編語言開發(fā)的應(yīng)用程序。要執(zhí)行這些應(yīng)用程序,需要底層CPU支持由匯編器形成二進(jìn)制的機(jī)器碼(由指令和數(shù)據(jù)組成)去運(yùn)行。
因此就需要底層計(jì)算平臺(tái)能夠支持該CPU的指令才可以,這也是在x86和鯤鵬編譯的區(qū)別之處。
在x86和鯤鵬上編譯之后的指令差異是哪些?可以參照下圖左側(cè),顯而易見這是一套非常簡(jiǎn)單的代碼,分別在x86和鯤鵬上編譯之后形成三點(diǎn)指令差異:
首先是匯編不同,x86上是兩條mov指令,通過把A和B的變量從內(nèi)存當(dāng)中取到寄存器,并將兩值相加,再由一條mov指令寫回內(nèi)存;鯤鵬上則是通過兩條ldr指令、一條add指令以及一條str指令完成整個(gè)過程。
其次是指令長(zhǎng)度不同,x86上mov指令是24位的,ldr指令是16位的,在鯤鵬上則都是32位;第三則是寄存器不同,x86和鯤鵬處理器使用的向量寄存器不同,其向量指令級(jí)也存在差異。
鯤鵬處理器與x86處理器的指令差異
這也正是做遷移的原因,因?yàn)樵趚86上所編譯出來的應(yīng)用程序因?yàn)橛幸陨先c(diǎn)的不同,因此無法在鯤鵬上直接運(yùn)行。
從x86到鯤鵬,遷移五步走戰(zhàn)略
從大量的實(shí)踐中得以總結(jié)出一些規(guī)律和方法,主要分為以下5個(gè)步驟:
1、遷移準(zhǔn)備,主要以收集硬件信息和軟件棧信息為主;
在這期間,主要收集硬件和軟件信息。硬件方面的信息主要是收集芯片和服務(wù)器的型號(hào),從而方便提供配置性能差不多的鯤鵬服務(wù)器;其次是收集軟件棧信息,主要分為操作系統(tǒng)、虛擬機(jī)、中間件、編譯器、上層依賴的開源軟件、商業(yè)軟件、業(yè)務(wù)軟件等信息。
2、遷移分析,對(duì)收集到的信息和軟件棧做初步分析,判斷是否真正需要遷移,評(píng)估遷移的工作量;
下圖左側(cè)就是一個(gè)非常完善的技術(shù)棧,底層有芯片,中間層為OS、虛擬機(jī)、編譯器等相對(duì)應(yīng)的運(yùn)行環(huán)境。上層是業(yè)務(wù)軟件,分為開源、自研和商用軟件。
開源軟件的遷移相對(duì)較為簡(jiǎn)單,其中一部分開源軟件在ARM上已經(jīng)被編譯好的包,直接下載即可。即便沒有現(xiàn)成的編譯成果,自行下載原碼進(jìn)行編譯也并不復(fù)雜方便;自研軟件的遷移需要注意語言類型的差異,編譯型語言是需要重新編譯之后才能運(yùn)行在新環(huán)境上,但是對(duì)于解釋型的語言來說就沒有重新編譯的需要,只要更換所依賴的虛擬機(jī)就可以;商用軟件則較為麻煩一些,首先可以通過聯(lián)系廠商獲取它對(duì)應(yīng)ARM架構(gòu)下的軟件版本,如果沒有的話就需要尋找有類似功能的軟件做替換。
此外像運(yùn)行環(huán)境、虛擬機(jī)、編譯器和操作系統(tǒng)這些也是要進(jìn)行替換,但是這些并非需要重新編譯,因?yàn)樵谌A為云鯤鵬論壇內(nèi)有軟件倉(cāng)庫(kù),可以直接去軟件倉(cāng)庫(kù)下載由鯤鵬官方所做的經(jīng)過驗(yàn)證的版本。
3、編譯遷移,分析完成之后就可以著手遷移工作,主要分為代碼遷移和軟件包遷移;
遷移分析之后可以進(jìn)行代碼的編譯和打包,編譯主要涉及兩個(gè)到代碼遷移和軟件包遷移。
其中代碼遷移需要區(qū)分語言,像C/C++和指令級(jí)的差異是比較大的,因此在x86上編譯出來的應(yīng)用程序無法在在鯤鵬上直接使用,因此要在鯤鵬上重新編譯才可以。此外編譯型語言所涉及的修改點(diǎn)相對(duì)更多,因?yàn)榇a當(dāng)中有可能蘊(yùn)含一些對(duì)指令級(jí)相關(guān)的宏定義或者功能性函數(shù);但是對(duì)于Java/Python這種解釋型語言來說就會(huì)簡(jiǎn)單很多。如果是純Java/Python的程序,就無須做編譯,因?yàn)楸旧淼奶摂M機(jī)已經(jīng)對(duì)指令級(jí)進(jìn)行了屏蔽,只要更換虛擬機(jī)就可以。
對(duì)于軟件包遷移來說,首先需要掃描該軟件包是否存在依賴庫(kù)或者依賴的可執(zhí)行程序,這些庫(kù)和可執(zhí)行程序如果是用C語言寫的是需要重新編譯的,編譯之后重新把軟件包打包即可。
4、性能調(diào)優(yōu),驗(yàn)證完成之后對(duì)性能指標(biāo)進(jìn)行測(cè)試,進(jìn)行性能調(diào)優(yōu);
由于大部分軟件對(duì)性能都有要求,因此在遷移完成之后需要對(duì)性能進(jìn)行調(diào)優(yōu),這里總結(jié)了【建立基準(zhǔn)-壓力測(cè)試-確定瓶頸-實(shí)施優(yōu)化-確認(rèn)效果】這五步法。
首先需要建立調(diào)優(yōu)基準(zhǔn),該基準(zhǔn)根據(jù)當(dāng)前的硬件配置、組網(wǎng)、測(cè)試模型來做綜合評(píng)估,以建立合理的條有目標(biāo);其次在調(diào)優(yōu)目標(biāo)建立后,通過壓測(cè)工具對(duì)軟件或系統(tǒng)進(jìn)行加壓,在加壓過程中暴露性能瓶頸,確定瓶頸之后對(duì)瓶頸進(jìn)行優(yōu)化;第四,注意在優(yōu)化過程中要及時(shí)記錄,因?yàn)閮?yōu)化并不一定是正向的,出現(xiàn)負(fù)向優(yōu)化時(shí)需要及時(shí)回退;最后在優(yōu)化措施實(shí)施完成后,需要重新啟動(dòng)壓力測(cè)試工具以確認(rèn)優(yōu)化效果。
這個(gè)過程并非一蹴而就,有可能其中某個(gè)步驟需要經(jīng)過多次循環(huán)之后才能達(dá)到既定目標(biāo)。
5、測(cè)試與認(rèn)證,保障商用上線。
和日常軟件開發(fā)一樣,需要對(duì)其進(jìn)行功能、性能、長(zhǎng)穩(wěn)等層層測(cè)試,以確保能達(dá)到商用標(biāo)準(zhǔn)。此外也可以拿軟件和系統(tǒng)到鯤鵬上做鯤鵬展翅認(rèn)證,其可以擴(kuò)展應(yīng)用的軟件使用空間并能夠加入鯤鵬生態(tài)。
C/C++代碼編譯原理及構(gòu)建流程
編譯型語言,從源碼到可執(zhí)行程序的歷程
C、C++、GO都是非常典型的編譯型語言,編譯型語言所開發(fā)的程序從x86平臺(tái)移植到鯤鵬平臺(tái)時(shí)一般都需要重新編譯才能運(yùn)行,這點(diǎn)上文也已經(jīng)提到了。那么為什么需要重新編譯才能運(yùn)行呢?接下來舉個(gè)簡(jiǎn)單的例子。
上圖為test.c的源碼文件,首先經(jīng)過預(yù)處理,把代碼里面以#號(hào)開頭的代碼片斷編譯為預(yù)處理文件,預(yù)處理文件再經(jīng)由編譯生成匯編代碼。匯編代碼經(jīng)過匯編器生成目標(biāo)文件,這也就是常說的機(jī)器碼。然而機(jī)器碼是無法直接運(yùn)行的,所以需要聯(lián)接動(dòng)態(tài)庫(kù)或者靜態(tài)庫(kù)來最終生成可執(zhí)行文件。
編譯構(gòu)建的過程
從代碼工程的角度看,其可以分為兩類:一類是編譯構(gòu)建的腳本,二是源碼。在編譯構(gòu)建的腳本中一般會(huì)存在Makefile、cmakelist等一系列腳本文件,C和C++的源碼一般是有src、tests等文件。
那么編譯構(gòu)建腳本類文件在遷移過程中會(huì)涉及哪些因素?一般會(huì)涉及到編譯選項(xiàng)的移植,源碼類文件會(huì)涉及到編譯宏,另外可能還會(huì)有編譯器自帶的Builtin函數(shù)的移植、SSE intrinsic函數(shù)移植等。需要強(qiáng)調(diào)的是這里提到的是遷移過程中可能會(huì)涉及到的移植項(xiàng),但在實(shí)際遷移過程中可能只需要編譯選項(xiàng)或修改編譯宏就可以。
C/C++代碼編譯構(gòu)建過程
首先要從獲取源碼開始,可以通過GitHub等開源社區(qū)來獲取;其次需要選擇所需的編譯環(huán)境,就是安裝編譯器gcc等;之后根據(jù)源碼的編譯腳本生成Makefile文件,再用Makefile編譯生成可持續(xù)文件。如果這部分代碼之中有依賴x86平臺(tái)的SO庫(kù),那么這部分的依賴庫(kù)是需要重新編譯替換的。在編譯完成之后進(jìn)行安裝部署,之后進(jìn)入到實(shí)際的系統(tǒng)之中進(jìn)行測(cè)試。
典型的移植類問題
在對(duì)編譯構(gòu)建的流程有基本理解后,就需要深入了解實(shí)際遷移過程中所涉及到的各種移植項(xiàng)。
1.編譯腳本和編譯選項(xiàng)的移植
以上圖為例,其中x86下-m64代碼的主要功能是將應(yīng)用程序編譯為64位,對(duì)應(yīng)到鯤鵬上是用-mabi=lp64的編譯選項(xiàng)。上文有提到這編譯選項(xiàng)需要在腳本中修改,對(duì)應(yīng)的Cmakelists里有可能存在add_defin等多種定義方式。
再看常用的數(shù)據(jù)類型移植,眾所周知x86平臺(tái)上默認(rèn)的char類型是一種有符號(hào)的類型,對(duì)應(yīng)到鯤鵬上則是無符號(hào)類型。因此在移植過程中需要顯示定義并將char類型定義為有符號(hào)。一種方法是在源代碼里加上signed char,但是缺點(diǎn)是可能改不全從而引發(fā)一些不可預(yù)知的問題。另一種方法是直接用fsigned-char來修改,在不同架構(gòu)下差異化的編譯選項(xiàng)也可以通過gcc文檔進(jìn)行查詢。
2.編譯宏的移植
如果有相同的代碼片斷在不同平臺(tái)下可能會(huì)存在不同分支,需要將不同架構(gòu)下的性能優(yōu)勢(shì)發(fā)揮到較高水平。但是對(duì)于編譯器來說,如何才能得知要編譯哪些分支代碼呢?這就是編譯宏的作用。
如果大家對(duì)大型開源軟件有接觸過,相信對(duì)上圖這些編譯選項(xiàng)都不會(huì)陌生。gcc編譯器所自帶的x86編譯選項(xiàng)就是x86_64,對(duì)應(yīng)到鯤鵬平臺(tái)上是ark-64。當(dāng)然除了gcc編譯器自帶的自定義宏,在實(shí)際場(chǎng)景中也需要對(duì)自研代碼進(jìn)行自定義,在鯤鵬上也是需要進(jìn)行自定義替換。
不過針對(duì)編譯宏的替換只是其中一個(gè)方面,其最重要的是對(duì)編譯宏下面的代碼實(shí)現(xiàn)移植。x86代碼上有些編譯器自帶自定義宏,比如smd屬性相關(guān)的宏在x86上是SSE開頭的宏,對(duì)應(yīng)到鯤鵬平臺(tái)上就需要自定義它的編譯宏和所相對(duì)應(yīng)的分支。
3.Builtin函數(shù)移植
Builtin函數(shù)是編譯器自帶的函數(shù),其在實(shí)際遷移項(xiàng)目中相當(dāng)常見,主要是crc32校驗(yàn)值的計(jì)算。需要移植的普通builtin函數(shù)實(shí)際并不多,大部分需移植的builtin函數(shù)集中在SSE intrinsic函數(shù)內(nèi)。
通過上圖可以看到在x86平臺(tái)上其和在鯤鵬平臺(tái)上是類似的,從命名來看有差異的地方就只存在于架構(gòu)。
4.內(nèi)聯(lián)匯編函數(shù)的移植
內(nèi)聯(lián)匯編對(duì)于部分開發(fā)者來說平時(shí)接觸的會(huì)比較少,所以又可能會(huì)感覺到陌生。
上圖列舉了將字節(jié)序進(jìn)行反序的例子,比如0X56781314反序輸出的是0X14137856,x86上對(duì)應(yīng)的是bswap指令,鯤鵬對(duì)應(yīng)的是rev指令,其它有些操作和寄存器都是基于內(nèi)聯(lián)匯編的語法規(guī)則進(jìn)行替換的。上圖的另一個(gè)例子是Builtin函數(shù),列舉了內(nèi)聯(lián)匯編轉(zhuǎn)換用鯤鵬上面的Builtin函數(shù)做替換的例子。比如popcount是對(duì)二進(jìn)制數(shù)里面的1進(jìn)行計(jì)數(shù),對(duì)應(yīng)到鯤鵬平臺(tái)上所替換的是popcountll。
5.SSE intrinsic函數(shù)移植(SIMD技術(shù))
關(guān)于SSE intrinsic函數(shù)的移植,在這之前需要先了解SIMD的技術(shù)。SIMD(Single Instruction Multi Data)是一種單指令處理多數(shù)據(jù)流的并行處理技術(shù),能夠在批量數(shù)據(jù)操作時(shí)進(jìn)行向量 化運(yùn)算加速,具有較高的執(zhí)行效率,在多媒體處理、矩陣運(yùn)算等場(chǎng)景都有廣泛的應(yīng)用。
Intel的SIMD擴(kuò)展指令統(tǒng)稱SSE,主要分為三類,MMX是64位寄存器,SSE到SSE4是28位的,三是AVX256和AVX512。鯤鵬基于SIMD的技術(shù)發(fā)展比較成熟,現(xiàn)在有些基于開源量的NEON庫(kù)主要是在圖象處理和視頻處理層面。
6.SSE intrinsic函數(shù)移植(MMX/SSE)
經(jīng)過調(diào)用編譯器就能夠基于C函數(shù)調(diào)用完成對(duì)SIMD技術(shù)的應(yīng)用,極大方便了開發(fā)者。
以上圖為例,在x86上用的是-m64的向量,add是關(guān)鍵字,而且這是加法運(yùn)算,后面32是數(shù)據(jù)類型。對(duì)應(yīng)到鯤鵬上是int32×2然后再做加法運(yùn)算,這常用的C函數(shù)規(guī)則是類似的。針對(duì)SSE指令,從內(nèi)存中加載4個(gè)單精度浮點(diǎn)數(shù)據(jù)到寄存器,x86是load,對(duì)應(yīng)到鯤鵬用的是vld1q。
7.SSE intrinsic函數(shù)移植(AVX)
AVX指令和MMX類似,只不過其位數(shù)不同。以AVX指令使用了256位寄存器運(yùn)算為例,向量A和向量B中分別存儲(chǔ)了8個(gè)單 精度浮點(diǎn)型(32位)。該指令將向量A和向量B中的8個(gè)數(shù)值分別相加,并將結(jié)果以返回值的形式返回 (結(jié)果中依然是8個(gè)單精度浮點(diǎn)型數(shù)據(jù)) ,最后再?gòu)南蛄考拇嫫髦蟹謩e取出8個(gè)單精度浮點(diǎn)數(shù)累加得到結(jié)果。
對(duì)應(yīng)到鯤鵬方面,鯤鵬處理器采用精簡(jiǎn)指令集,使用128位寄存器實(shí)現(xiàn)SIMD(Single Instruction Multi Data)計(jì)算。在實(shí)現(xiàn)本例16個(gè)浮點(diǎn)數(shù)的相加時(shí),通過兩條vaddq_f32指令來分別完成,每條指令完成兩組共8個(gè)浮點(diǎn)數(shù)算,最后再?gòu)南蛄考拇嫫髦蟹謩e取出8個(gè)浮點(diǎn)數(shù)累加。
寫在最后
對(duì)于開發(fā)者而言,代碼和軟件遷移是一套必須要掌握的技能。尤其是各種智能終端數(shù)量暴漲,物聯(lián)網(wǎng)飛速發(fā)展的當(dāng)下,x86平臺(tái)已經(jīng)難以適應(yīng)全生態(tài)的發(fā)展,從x86遷移至ARM平臺(tái),正是現(xiàn)在的大勢(shì)所趨。而鯤鵬生態(tài),則為每一位有遷移需求的開發(fā)者提供了最便利的工具和環(huán)境。沒有哪一款平臺(tái)是最好的,只有最適合業(yè)務(wù)的那款平臺(tái),從x86到ARM,答案正在逐漸清晰。
- 蜜度索驥:以跨模態(tài)檢索技術(shù)助力“企宣”向上生長(zhǎng)
- 為什么年輕人不愛換手機(jī)了
- 柔宇科技未履行金額近億元被曝已6個(gè)月發(fā)不出工資
- 柔宇科技被曝已6個(gè)月發(fā)不出工資 公司回應(yīng)欠薪有補(bǔ)償方案
- 第六座“綠動(dòng)未來”環(huán)保公益圖書館落地貴州山區(qū)小學(xué)
- 窺見“新紀(jì)元”,2021元宇宙產(chǎn)業(yè)發(fā)展高峰論壇“廣州啟幕”
- 以人為本,景悅科技解讀智慧城市發(fā)展新理念
- 紐迪瑞科技/NDT賦能黑鯊4 Pro游戲手機(jī)打造全新一代屏幕壓感
- 清潔家電新老玩家市場(chǎng)定位清晰,攜手共進(jìn),核心技術(shù)決定未來
- 新思科技與芯耀輝在IP產(chǎn)品領(lǐng)域達(dá)成戰(zhàn)略合作伙伴關(guān)系
- 芯耀輝加速全球化部署,任命原Intel高管出任全球總裁
免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁(yè)或鏈接內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會(huì)依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。