龔宇潔
方舟編譯器初探*
龔宇潔
(武漢城市職業(yè)學(xué)院,湖北 武漢 430070)
2019-04,華為首次公開了自主研發(fā)的方舟編譯器,2019-08-31開源編譯器框架代碼,從華為的設(shè)計(jì)思想和框架設(shè)計(jì)來看,方舟編譯器將會(huì)在業(yè)界帶來一場(chǎng)安卓性能革命。作為一名Android開發(fā)者,對(duì)方舟有限的資源和開源內(nèi)容進(jìn)行了學(xué)習(xí)和解讀,結(jié)合安卓編譯器發(fā)展的研究,對(duì)方舟編譯器進(jìn)行了初步的探索。
方舟編譯器;Android;多語言設(shè)計(jì);設(shè)計(jì)方案
2019-04,華為舉行了P30手機(jī)發(fā)布會(huì),在展示手機(jī)產(chǎn)品的同時(shí),首次公開了華為自主研發(fā)的方舟編譯器,稱之為“安卓性能革命”,能夠解決安卓程序“邊解釋邊執(zhí)行”的低效,構(gòu)級(jí)優(yōu)化,顯著提升性能。系統(tǒng)操作流暢度提升24%,系統(tǒng)響應(yīng)提升44%,三方應(yīng)用操作流暢度提升60%,并將測(cè)試視頻進(jìn)行了展示,同時(shí)承諾向業(yè)界開源。2019-08-31,華為方舟編譯器開源官網(wǎng)正式上線,開源編譯器框架代碼,包括編譯器IR(Intermediate Representation)、RC(Reference Counting)和多語言設(shè)計(jì)思想等,用于與行業(yè)、學(xué)術(shù)界交流和學(xué)習(xí)。雖然華為還沒有開源完整的方舟編譯器,但從華為的設(shè)計(jì)方案和框架設(shè)計(jì)來看,方舟編譯器確實(shí)能提升安卓應(yīng)用程序的運(yùn)行效率,這將會(huì)在業(yè)界帶來一場(chǎng)安卓性能革命。
對(duì)于編程常用的C/C++程序語言或Java程序語言,計(jì)算機(jī)識(shí)別不了,計(jì)算機(jī)只能識(shí)別和執(zhí)行用“0”“1”這樣的二進(jìn)制數(shù)所表示的指令,用二進(jìn)制數(shù)表示的指令的集合稱之為機(jī)器語言。在計(jì)算機(jī)誕生初期,程序員在紙帶上打孔表示1,不打孔表示0,再將紙帶輸入計(jì)算機(jī)運(yùn)算,但在現(xiàn)代無法實(shí)現(xiàn)。
匯編指令是匯編語言的主體。機(jī)器指令運(yùn)用的是“0”“1”的組合,而匯編指令的格式更容易書寫和記憶,例如“MOV AX,BX”將寄存器BX的內(nèi)容發(fā)送到AX上。匯編語言程序和硬件相關(guān),不同的處理器匯編指令可能不同。程序員用匯編語言編寫程序比較復(fù)雜。
目前常用的C/C++、java等都是高級(jí)語言,高級(jí)語言從人類習(xí)慣的語言結(jié)構(gòu)出發(fā),更容易讀懂和表達(dá),高級(jí)語言與指令或者硬件的相關(guān)度低,更多是對(duì)數(shù)據(jù)的運(yùn)算和控制,通過算法實(shí)現(xiàn)具體功能。
高級(jí)語言程序需要通過編譯器變成匯編程序,然后通過匯編器變成機(jī)器代碼,最后才能被計(jì)算機(jī)執(zhí)行。其中C/C++是編譯語言,靜態(tài)編譯,即編譯器直接將程序編譯成機(jī)器碼,安裝到硬件設(shè)備上就能執(zhí)行。而Java為了實(shí)現(xiàn)跨平臺(tái)的操作,運(yùn)用虛擬機(jī)來調(diào)度硬件資源,虛擬機(jī)中包含了翻譯器或編譯器,Java是預(yù)編譯語言,動(dòng)態(tài)編譯,在開發(fā)環(huán)境中將源碼轉(zhuǎn)換成字節(jié)碼,再由虛擬機(jī)中的編譯器或解釋器轉(zhuǎn)換為機(jī)器語言。
Android應(yīng)用程序基于Java語言,所以都是依靠虛擬機(jī)進(jìn)行編譯或解釋的。2008年,Android1.0使用的是Dalvik的虛擬機(jī),里面集成了一個(gè)解釋器,用戶每一次打開Android應(yīng)用程序時(shí),解釋器就開始翻譯。它的執(zhí)行方式是一邊翻譯一邊執(zhí)行,因此其執(zhí)行效率很低。2010年發(fā)布的Android 2.2使用了JIT(Just in Time)即時(shí)編譯機(jī)制,即當(dāng)Android應(yīng)用程序運(yùn)行時(shí),會(huì)同時(shí)將用戶經(jīng)常使用的功能編譯為機(jī)器能直接執(zhí)行的機(jī)器碼,而不是碰到一句執(zhí)行一句。當(dāng)用戶使用了不常用的功能時(shí),再讓解釋器進(jìn)行翻譯。但缺點(diǎn)是不能一勞永逸,每次啟動(dòng)應(yīng)用程序都要重新編譯。2014年發(fā)布的Android 5.0,將Dalvik虛擬機(jī)換成了性能更好的ART(Android Run Time),同時(shí)把AOT (Ahead of Time)編譯器替代了JIT。AOT是指應(yīng)用程序在手機(jī)安裝時(shí)就把代碼先編譯成機(jī)器碼,這樣就不需要每次打開應(yīng)用程序的時(shí)候重新編譯。但其有2個(gè)缺點(diǎn):①占用存儲(chǔ)空間,編譯后的機(jī)器碼體積迅速膨脹;②程序安裝速度慢。
對(duì)于2017年的Android 7.0,Google對(duì)其進(jìn)行了改進(jìn),采用AOT+JIT+解釋執(zhí)行的方式,應(yīng)用程序安裝時(shí)不執(zhí)行編譯,安裝速度快。應(yīng)用之后,系統(tǒng)收集經(jīng)常被傳輸?shù)拇a信息,設(shè)備空閑時(shí)直接把這些代碼編譯為機(jī)器碼(AOT)。剩下的部分在運(yùn)行時(shí)通過JIT和解釋器實(shí)現(xiàn),用時(shí)間換效率,達(dá)到一種平衡。但無論如何演變,仍然只是在虛擬機(jī)上進(jìn)行優(yōu)化,虛擬機(jī)+編譯器+解釋器的結(jié)構(gòu)本身就是一種對(duì)硬件資源的占用,Java這樣的預(yù)編譯解釋型語言,每執(zhí)行一行代碼,先有解釋器解釋機(jī)器碼,然后再去執(zhí)行。其優(yōu)點(diǎn)是不同平臺(tái)只需要換用不同的解釋器;缺點(diǎn)是運(yùn)行效率低下,程序的運(yùn)行性能仍無法得到最大發(fā)揮。
Android編譯器演變?nèi)绫?所示。
表1 Android編譯器演變
Android版本1.02.25.07.0 虛擬機(jī)DalvikDalvikARTART 編譯機(jī)制解釋器JIT+解釋器AOTAOT+ JIT+解釋器
Android 1.5系統(tǒng)之后Google允許Java通過JNI(Java Native Interface)Java原生接口去調(diào)用一些由C/C++代碼開發(fā)的so庫,來實(shí)現(xiàn)和C/C++等代碼的互交。兩種不同框架的語言相互調(diào)用,JNI需要調(diào)用硬件資源來做調(diào)度,這種機(jī)制效率也很低。
當(dāng)內(nèi)存資源不足時(shí),C/C++需手動(dòng)釋放內(nèi)存,而Java可以自動(dòng)釋放內(nèi)存,Java虛擬機(jī)將會(huì)不定期自動(dòng)回收不再被使用的對(duì)象,這也是Java語言的重要優(yōu)點(diǎn)。但同時(shí)也造成了一些問題,當(dāng)內(nèi)存資源不夠時(shí),虛擬機(jī)運(yùn)用GC(Garbage Collection)機(jī)制進(jìn)行內(nèi)存資源回收,Java虛擬機(jī)所有運(yùn)行的線程將會(huì)暫停。雖然這個(gè)過程很短暫,但用戶是無法準(zhǔn)確控制的,如果是性能較差的手機(jī)可能還會(huì)出現(xiàn)“間歇性”卡頓的現(xiàn)象。
據(jù)官網(wǎng)介紹,方舟編譯器是為支持多種編程語言、多種芯片平臺(tái)的聯(lián)合編譯、運(yùn)行而設(shè)計(jì)的統(tǒng)一編程平臺(tái),包含編譯器、工具鏈、運(yùn)行時(shí)等關(guān)鍵部件。從開源框架來看有以下特點(diǎn)。
方舟編譯器也屬于AOT,所采用的機(jī)制是在程序編譯打包的時(shí)候已經(jīng)將Java代碼轉(zhuǎn)換成機(jī)器碼,將Java原本的動(dòng)態(tài)編譯改為靜態(tài)編譯,這樣提供給用戶的安裝文件所包含就已經(jīng)是機(jī)器碼了,不需要在用戶的手機(jī)上進(jìn)行編譯,即使是應(yīng)用程序安裝后首次運(yùn)行也會(huì)非常流暢。
方舟編譯器將同時(shí)支持Java和C/C++多種語言,包括混合語言,各種語言實(shí)現(xiàn)統(tǒng)一的編譯器中間表示(IR),使各種程序語言代碼在開發(fā)者環(huán)境中編譯成統(tǒng)一的可直接執(zhí)行的機(jī)器碼,具體如圖1所示。
圖1 多語言支持
方舟編譯器采用了引用計(jì)數(shù)法(RC,Reference Counting)來進(jìn)行內(nèi)存的實(shí)時(shí)回收,并且配合使用了專門的消除環(huán)算法(消除對(duì)象互相引用帶來的無法回收問題),來避免GC集中式回收帶來的系統(tǒng)卡頓。相比GC,方舟的內(nèi)存回收是實(shí)時(shí)的而非集中式的,且不需要暫停應(yīng)用進(jìn)程,這樣便大大消除了卡頓。
方舟編譯器的工作原理:生成的安裝包改變了Android原本的apk格式規(guī)則,但有可能目前的Android是無法兼容的,但從官網(wǎng)的演示代碼來看,輸出了so庫,so庫是C/C++通過Android的 ndk編譯之后生成的本地庫,是Android系統(tǒng)支持的,形成so庫能夠保證最后生成的安裝包文件和原生的apk文件格式一致;虛擬機(jī)的自動(dòng)回收內(nèi)存資源的工作也不需啟動(dòng),“間歇性”卡頓現(xiàn)象消失。
從官方發(fā)布的內(nèi)容看,方舟編譯器強(qiáng)大,始于安卓,強(qiáng)于安卓,趕超IOS,但是由于目前只開源的框架源碼和部分功能演示,所以方舟編譯器的具體表現(xiàn)如何還有待考證。既然方舟編譯器支持多語言和多種硬件平臺(tái),是否會(huì)發(fā)布一個(gè)與AndroidStudio類似的開發(fā)平臺(tái),也是值得期待的。中國計(jì)算機(jī)行業(yè)最根本的編譯器、操作系統(tǒng)、芯片等領(lǐng)域還是比較落后的,而華為是國內(nèi)為數(shù)不多有這個(gè)能力,并且愿意投入人力和物力在這幾個(gè)領(lǐng)域的企業(yè),華為需要的是時(shí)間,人們期待著方舟,期待著鴻蒙。
TP314
A
10.15913/j.cnki.kjycx.2019.23.018
2095-6835(2019)23-0047-02
龔宇潔(1984—),女,碩士研究生,研究方向?yàn)殡娮佑?jì)算機(jī)。
2017年武漢市教育局教學(xué)研究項(xiàng)目“‘互聯(lián)網(wǎng)+’背景下《Android應(yīng)用開發(fā)》課程學(xué)生自主學(xué)習(xí)策略研究”(編號(hào):2017162)
〔編輯:張思楠〕