方舟编译器
https://www.oschina.net/p/arkcompiler
华为方舟编译器作为一款全新的编译器可以显著提高手机的运行速度,它不采用现有编译器边解释边执行的模式,而是将这种动态编译改为静态编译,可以做到全程执行机器码,进而高效运行程序,大大缩短程序响应时间。
- 多语言联合:将同一应用中的不同语言代码联合编译、联合优化,消除语言间的性能 “鸿沟”,降低开发者的优化成本
- 轻量运行时:通过编译器的语言实现能力和优化能力增强,应用运行时的开销更小
- 软硬件协同:编译器与芯片实现软硬件协同优化,充分发挥硬件能效,应用体验更佳
- 多平台支持:支持面向多样化的终端设备平台进行编译和运行,根据设备特征提供便捷的开发与部署策略,提高开发效率
https://gitee.com/openarkcompiler/OpenArkCompiler
OpenArkCompiler 四个技术特点
能够将不同语言代码编译成一套可执行文件,在运行环境中高效执行:
- 支持多语言联合优化、消除跨语言调用开销;
- 更轻量的语言运行时;
- 软硬协同充分发挥硬件能效;
- 支持多样化的终端设备平台
关于华为方舟编译器,你想知道的都在这里! - 知乎 https://zhuanlan.zhihu.com/p/77108133
关于华为方舟编译器,你想知道的都在这里!
2017年5月的一个凌晨,华为某实验室,方舟编译器上第一个Java程序“HelloWorld”跑通了!
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616293-891362560.jpg)
当时项目组的一位工程师哽咽道:
“I never thought printing 'Hello, World' would be this hard .”(我从来没想到,打出"Hello,World"会如此艰难。)
十年前,华为启动编译组,到这一刻,初见曙光。
2019年4月,华为方舟编译器正式面世!
今天,我们聚焦华为「方舟编译器」,这个一发布就引起巨大响动的底层核心技术。
一、为什么需要「方舟编译器」?
安卓系统从2008年1.0到9.0,十来年间安卓系统大小版本超过15个。2016年开始,不断融入了华为等公司发起的文件系统、人工智能学习、智能硬件调度和内存管理等底层创新技术,安卓手机的体验已经今非昔比。但是,依然有四大方面难题,影响着安卓的体验。解决这四大难题,也是华为方舟编译器的使命。
1. Java的「虚拟机」
Java为了能够实现跨平台操作,便借助虚拟机来调度硬件平台资源。在虚拟机里,还需要集成翻译器或者编译器,来将Java的字节码(即中间代码)解释成机器听得懂的机器语言,或者直接编译成机器直接执行的010101的机器码。
2008年,Android 1.0刚发布的时候,使用的是一个叫Dalvik的虚拟机,里面集成了一个解释器,每次用户在安卓手机上运行APP时,就会叫醒这个解释器,来给安卓的硬件解释APP想要干嘛。这就相当于新闻发布会,发言人讲一句自己的母语,然后再由专业翻译将其翻译成外国记者听得懂的语言,效率非常低下,一个小时可能也问不了几个问题。
这个问题严重拖了安卓手机的后腿,所以一年多后的2010年,安卓2.2版本引入了JIT(Just in Time,即时编译)机制。JIT比较聪明,当用户在安卓手机运行APP时,会同时将用户经常使用的功能编译为机器能直接执行的010101机器码,不用一句一句地去翻译。当出现不常用的功能时,再把解释器叫起来翻译。
JIT虽然变聪明了一点,但是每次启动APP都要重新编译一次,不能一劳永逸。加上Dalvik虚拟机性能比较落后,所以2014年10月的Android 5.0版本将虚拟机从Dalvik替代成ART(Android Run Time),同时把JIT的编译器替代成AOT (Ahead of Time)。意思就是说,APP在下载后安装到手机上时同时把能编译的代码先编译成机器听得懂的010101。剩下不太好翻译的代码,就在用户使用时再叫醒解释器来翻译。AOT相比JIT的好处,就是不用每次打开APP都需要先编译一遍。但是,坏处就是用户安装APP的时间有点长。
越来越多的用户吐槽为什么安装一个APP也慢吞吞。于是,2017年的Android 7.0又做了一点改进,安装时先不编译中间代码,而是在用户空闲时将能够编译成机器码的那部分代码,通过AOT编译器先静态编译了。如果AOT还没来得及编译或者不能编译,再叫醒JIT+解释器两个难兄难弟来顶住。这种机制,相当于用时间换空间,既缩短了用户安装APP的等待时间,又将虚拟机里编译器和解释器能做的优化提升到最大效率了。
很多人以为华为方舟编译器就是Android 7.0的ART虚拟机,其实不然。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616337-1301049037.jpg)
无论是编译器还是解释器,只是在虚拟机上打补丁。手机上的虚拟机+编译器+解释器本身不仅占用硬件资源,还无法发挥好软件运行性能。对此,行业中不少厂商采用了提升安卓手机内存和存储空间的方法来弥补虚拟机的弊端。
2.额外的JNI开销
JNI,全称Java Native Interface(Java原生接口),用来和C/C++等代码进行交互。
目前95%的TOP应用都是使用Java和C/C++等多种语言混合开发而成。Java和C/C++属于两种不同架构的语言,各有自己的使用规范。为了APP正常运行,它俩之间需要互通有无,这个互通有无的接口就是JNI。在数据访问、函数调用、生命周期维护、异常处理等方面都需要这两种代码互相调用。这就意味着手机硬件资源要分配一部分给JNI去做调度。不仅占用了硬件资源,而且这种机制本身就效率较低。这便是额外的JNI开销。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616303-55534934.jpg)
3.安卓虚拟机的编译器受限于手机硬件和代码优化模板单一,代码优化空间有限
编译器包含三个部分。前端Front End,主要负责将源代码翻译成IR(Intermediate Representation,中间表示);中端的Optimizer主要负责代码优化,将前端翻译过来的IR代码优化得更高效;后端Back End则将优化后的IR编译成010101的机器码。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616330-1140510212.jpg)
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616330-1140510212.jpg)
为了防止生态过于碎片化,安卓只为第三方开放了简单的编译代码优化模板,代码优化空间有限。
4.Java现有内存回收机制容易造成「间歇性」卡顿
当手机内存资源不够用的时候,安卓虚拟机就会召唤GC(Garbage Collection)“封锁公路”,让所有手机运行的Java线程全部暂停,等待它回收内存空间,避免“交通流量超载”。这个GC机制,无法精确控制和干预,用户也无法把它去掉,所以性能比较差的手机还存在“间歇性”卡顿。
十余年间,通过安卓系统的持续优化,以及内存的不断加持,安卓手机构筑了足够流畅的用户体验。但是安卓的四大难题,一直影响着安卓手机的体验。
对此,华为科学家和工程师们持续攻关了十年。
二、十年方舟
2009年,华为启动5G基础技术研究,同时开始创建编译组,第一批海内外研究人员加入。
2013年,华为推出面向基站领域的自研编译器HCC,并正式提出编译器框架构想。
2014年,众多海内外知名专家加入华为,方舟项目正式启动。
2016年,成立编译器与编程语言实验室。
2019年,华为方舟编译器正式面世!
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616265-837638322.jpg)
这十年,每一次攻关都蕴含着华为软件工程师们的倾力投入,每一个进展都值得铭记。
2017年5月,方舟编译器上第一个Java程序“HelloWorld”跑通。
2017年8月的一个凌晨,在华为的一个实验室里,项目组已经连续数日24小时不间断攻关,却始终看不到success的返回信息。绝望之下,工程师把所有通信数据打印出来,逐个字节排查,最终发现有一处字节的顺序不一致。纠正后,华为方舟跑通了第一个安卓后台服务DiskStatus,这标志着对安卓的改造进入了实操阶段。
2018年春节前一周,方舟编译器跑通安卓系统所有后台服务,并成功移植到手机。
接下来,项目组在除夕前夜启动了方舟编译手机的Beta测试。大年初一清晨,总架构师发来了第一条经编译器编译的运行程序发出来的拜年消息:
「春节快乐,方舟大吉!」
当P30发布会上「方舟」甫一出现,就在中国软件行业掀起热烈的讨论。实际上,方舟已经不是传统意义上从高级语言到机器码的“万能翻译”,更是一个编译运行系统。
一方面,方舟编译器首次在Java领域将虚拟机干掉了,也是软件史上首次将Java/C/C++等混合代码一次编译成机器码直接在手机上运行,彻底告别Java的JNI额外开销,也彻底告别了虚拟机GC内存回收带来的应用进程掉线,使操作流畅度大幅提升。如果说目前最新的安卓系统是和谐号动车,那么经方舟编译的安卓系统便是高铁,是「复兴号」。
华为手机直接通过方舟编译器替换了Android system-server的所有后台服务,这一项就已经足够让华为EMUI更快一步。根据华为官方测试,方舟编译器提升手机系统操作流畅度高达24%,系统响应性能提升44%。入手搭载EMUI 9.1的手机用户,应该已经体验到了。
另一方面,方舟编译器用空间换性能,直接将编译器的代码优化搬到了开发者环境,不再被手机端的硬件资源所限制,为代码优化提供了无限可能。
此外,经测试,新浪微博极速版APP经方舟编译后,操作流畅度提升高达60%。
三、干掉虚拟机
方舟编译器从立项开始,就是要干掉虚拟机。这在历史上,是没有人做到的。
SUN公司当初发明Java语言,就是借助虚拟机的这个「万能中转站」,屏蔽掉各种硬件的差异,方便同一个代码在多个平台运行,所以Java是目前最流行的高级编程语言之一。这么多年没有人能够干掉虚拟机,说明难度非常之大。
那么方舟编译器,是如何干掉虚拟机的呢?
最关键的就是要能够将Java代码直接编译成010101的机器码。
这种设想理论上可行,但是从现实来讲太难了。历史上有过一些尝试,比如现在的安卓ART虚拟机。这些尝试能够提前翻译Java语言里很多的静态语义,但是多数的动态语义,仍然搞不定,还得交给虚拟机。
所谓静态语义,我们可以理解为确定的语言和意思,比如「我是张三」;而动态语义,则需要结合上下文去理解,比如「能穿多少就穿多少」,到底穿多还是穿少,要看上下文讲的是冬天还是夏天了。大家熟悉的APP开屏广告就需要用到动态语义。
为了这个目标,华为软件工程师们对自己非常苛求,这里涉及到大量的细节,从对象模型的设计,到每一个bit的用途、每一个对象的元数据metadata(描述数据的数据)、每一个编译优化的设计,都经过了无数次的激烈讨论和推倒重来。
最终,方舟编译器通过编译阶段和运行阶段的双向加持,将静态编译动态语义的两大难点一一解决:一是设计数据模型,二是如何在运行时高效获得动态信息。方舟编译器团队基本遍历了Java的动态语义,进行了大规模的数据建模。同时,大大提高了编译时动态语义分析的精度,特别是涉及跨语言调用时;另外,华为设计了一套具有核心专利的动态语义匹配机制,有效降低了运行时动态语义的开销。
正是因为这两大难点的突破,让方舟编译器能够将Java代码编译成机器能直接执行的语言。经过华为方舟编译器的APP,再也不需要在手机上编译了,从此告别了虚拟机,带来了非常流畅的安卓体验。
四、代码「万国通」
95%的Top应用都是Java/C/C++等混合语言编写而成。方舟编译器的第二个使命,就是去掉混合语言互相调用带来的JNI开销。
华为方舟编译器团队基于多个编程语言的深刻理解和大量研发积累,将混合语言首次实现了统一的中间表示IR,这就相当于同一个人能够理解全世界的语言,所以我们把这个突破叫做代码「万国通」。
那么方舟编译器是如何使用统一的IR来表示各种语言呢?
IR是用来表示代码的数据结构,它是编译器的各模块以及相关工具之间用来传递信息的「协议和通用语言」,也是程序变换和编译优化各种算法的承载体。它是编译器的“大脑”,直接决定了编译器的最终效果。它的难度是最高的。
华为方舟编译器团队对IR进行了长达五年的精雕细琢,逐渐摸索出“大脑”里每一条神经、每一个神经元的信号规律,并在此基础上发明了一套核心专利,使得不同语言代码在开发者环境中能够统一编译成同一套可直接执行的机器码,从而消除了混合语言互相调用的开销。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616340-1631206993.jpg)
五、给代码装上飞机发动机
除了IR,编译器还有一个非常重要的价值,就是代码优化。
华为方舟编译器,直接将代码优化从手机环节搬到了开发者环境,未来还可能搬到云端。利用开发者环境更强大的算力,可以实现更先进和精细的优化算法,来达到更强大的优化效果,在很多特定场景,代码优化的提升效果甚至是颠覆性的。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616299-1531036808.jpg)
这相当于给APP在方舟里装上飞机发动机,让APP运行如飞!
值得一提的是,开发者使用方舟编译器,并不需要改变原来的编码习惯。开发者可以自行开发代码优化算法,也可以仅通过方舟编译器预置的算法进行代码优化。未来,华为还将提供代码调优工具,开发者可以选择根据工具的优化建议来调整代码,和方舟编译器配合获得更优的执行效果。我们希望,未来广大APP开发者使用方舟编译器,消费者们将会得到更好的体验。
六、再见卡顿!
方舟的第四个使命,就是解决安卓虚拟机GC内存回收带来的卡顿。
目前安卓手机内存资源不够用的时候,GC直接叫停所有应用,所以偶尔会遭遇莫名卡顿。
方舟编译器采用了引用计数法(RC,Reference Counting)来进行内存的实时回收,并且配合使用了专门的消除环算法(消除对象互相引用带来的无法回收问题),来避免GC集中式回收带来的系统卡顿。相比GC,方舟的内存回收是实时的而非集中式的,且不需要暂停应用进程,这样便大大消除了卡顿。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616356-1703108549.jpg)
如果把内存回收比作打扫房间,那么GC的策略是专门有一个卫生员,看房间里垃圾太多了,就把所有人请出去,打扫完了再让大家回来。而方舟的RC则是每个人收拾自己的垃圾,用完就清理,保持清洁的同时不影响人的正常活动。
软件有一个大家都很熟悉的死循环,就是电脑被一个无限循环的运行程序把计算机资源占光。
这种“死循环”在软件中叫“环引用”。为了从机制避免手机内存被环引用“吃掉”,方舟编译器引入annotation的“告警”标示,对基础类的环进行标注。当然,Java程序员也可以对业务代码中的环进行标注。经过丰富的实践验证,方舟这种机制可以减少大部分程序中环的出现。另外一方面,方舟编译器在运行状态下引入了高效的环回收机制,允许有选择地智能回收某个APP的内存占用,这对传统的环回收算法是一个非常棒的改进。
安卓卡顿再见!
正是因为方舟做到混合语言的统一中间表示和完全静态编译,它干掉了虚拟机,消除了JNI开销,告别了GC内存回收的“间歇性”卡顿,以及其他很多开销。同时,为开发者进行代码优化提供了一个更广阔的舞台。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616304-1635724716.jpg)
科技的进步,离不开全球无数科学家和工程师的奉献,产业的繁荣,更离不开开放合作!8月9日-8月11日2019华为开发者大会,我们期待和知友们进一步探讨!
文章来源:菊厂搞机
本文参考文献及资料:
1.《人类简史》尤瓦尔·赫拉利著
2.《IT通史:计算机技术发展与计算机企业商战风云》李彦编著
3.《华为王成录现场采访手稿和PPT》
4. 华为相关研发专家调研和访谈
5. 维基百科、CSDN、知乎等互联网资讯
关于方舟编译器的更多内容,你还可以戳链接了解更多:
链接:https://www.zhihu.com/question/319688167/answer/661413209
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方舟编译器虽然是在 4.11 日 HUAWEI P30 系列国内发布会上公布的应用编译技术,但其实华为早在 5 年前就开始布局,并投入数百专家团队,历经多次尝试,才在 EMUI 9.1 上实现了机器代码的翻译。
首先,什么是编译技术?
几千年来,人们从裹腹耐寒到智慧创新,从未停止探索世界的步伐。同时,他们将这些智慧赋予更多的物体,比如机器。
想让机器读懂人类情感,他们之间就需要有个“翻译”,来充当人机交互的桥梁,也就是专业人士口中的编译技术。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616337-666767.jpg)
它能够将 C、Java 等高级语言转换为机器能读懂的低级语言,将精妙的代码转化为 0 和 1 的二进制指令,消除了沟通障碍,从而驯服了机器。
可以说编译器是软件与芯片之间的桥梁,其性能,效率直接影响到机器的运行效率。
方舟编译器和 Java 不得不说的故事
而既有的安卓系统框架与应用之间,仍然使用的是不被机器直接读懂的 Java 语义,最初的解决方案是通过增加一个虚拟机制(JVM),相当于一个“中间层”将 Java 语言“翻译”为机器可以读懂的汇编指令。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616489-1376692205.jpg)
“中间层”翻译一句 Java 语义机器就执行一段,也就是“边解释边运行”(动态编译),不但效率低,耗费系统资源,对操作流畅度也有影响。
尽管安卓系统 6.0 以后采用了 ART (Android Runtime)模式,对调用次数多的 Java 代码编译为机器码(静态编译);在设备空闲的时候进行一些预编译,解决了部分 Java 代码执行效率问题,但对于动态语义部分还是无法实现静态编译,仍需要虚拟机充当“翻译”边解释边运行,效率和体验提升有限。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616309-284175072.jpg)
而方舟编译器,采用了全新的系统及应用的编译和运行机制,对所有的 Java 语义全部做到静态编译,直接将 Java 语言“翻译”成机器语言(静态编译),消除了虚拟机动态编译的额外开销,实现了开发和运行效率的兼容并举。
如果把编译器看做一个翻译,就好比我们去到一个语言不通的国家,原本只能通过同声翻译(虚拟机)来进行交流沟通,难免效率低下。而华为方舟编译器更像是让您直接获得了语言能力,从而可以摆脱同声翻译(虚拟机),可以更畅快地与当地人沟通。
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616454-1840605882.jpg)
根据华为实验室的测试数据,EMUI 9.1 在仅仅对系统组件 System Server 应用了华为方舟编译器后,系统操作流畅度提升 24%,系统响应性能提升 44%。同时,新浪微博极速版在应用方舟编译器之后,操作流畅度最高提升了60%。[1]
![](https://img2022.cnblogs.com/blog/1006507/202209/1006507-20220926133616309-778815057.jpg)
方舟编译器编译的应用在开发阶段就已完成。也就是说,只要是经过编译器编译的应用,在应用市场上上架了以后,用户下载的就是编译过的了。
说了这么多,看个视频,一分钟了解一下华为方舟编译器吧!
综上所述,方舟编译器作为全新的系统及应用的编译和运行机制,从 DNA 层面对安卓进行了改造,打破了性能和功耗的的跷跷板,解决了安卓应用变解释边运行的低效问题,让手机能直接听懂“高级语言”,可以说是近几年来安卓阵营最大的根本性革新。它解决了安卓系统久用必卡顿的魔咒,打破了人机之间的藩篱,让用户能直观感受到的就是:
1、 提升了应用的流畅度;
2、 降低手机 CPU 的开销;
3、 进一步降低功耗提升了手机续航能力;
4、 为用户带来更加持久流畅的体验。
发布会上余总也表示方舟编译器将会在 EMUI 后续的版本开发中运用到更多模块中,并且面向业界全面开源,更多开发者可参与到方舟编译器的开发、使用中。那么方舟编译器的效果究竟如何,我们拭目以待吧!
除了方舟编译器以外,EMUI 9.1还带来了全新的EROFS文件系统,继续深度了解戳:
全新的华为EMUI 9.1系统,又有哪些新特性?
最后,关注
知乎机构号,获取更多新品资讯与深度解读!也欢迎在手机中使用“玩机技巧”APP,解锁更多新机玩法,快速入门新手机~
参考
- ^数据来源于华为实验室。第三方应用为新浪微博极速版,后续可到华为应用市场下载最新版本体验。