方舟编译器初探*
2019-12-19龚宇洁
龚宇洁
方舟编译器初探*
龚宇洁
(武汉城市职业学院,湖北 武汉 430070)
2019-04,华为首次公开了自主研发的方舟编译器,2019-08-31开源编译器框架代码,从华为的设计思想和框架设计来看,方舟编译器将会在业界带来一场安卓性能革命。作为一名Android开发者,对方舟有限的资源和开源内容进行了学习和解读,结合安卓编译器发展的研究,对方舟编译器进行了初步的探索。
方舟编译器;Android;多语言设计;设计方案
1 概述
2019-04,华为举行了P30手机发布会,在展示手机产品的同时,首次公开了华为自主研发的方舟编译器,称之为“安卓性能革命”,能够解决安卓程序“边解释边执行”的低效,构级优化,显著提升性能。系统操作流畅度提升24%,系统响应提升44%,三方应用操作流畅度提升60%,并将测试视频进行了展示,同时承诺向业界开源。2019-08-31,华为方舟编译器开源官网正式上线,开源编译器框架代码,包括编译器IR(Intermediate Representation)、RC(Reference Counting)和多语言设计思想等,用于与行业、学术界交流和学习。虽然华为还没有开源完整的方舟编译器,但从华为的设计方案和框架设计来看,方舟编译器确实能提升安卓应用程序的运行效率,这将会在业界带来一场安卓性能革命。
2 基本概念
2.1 机器语言
对于编程常用的C/C++程序语言或Java程序语言,计算机识别不了,计算机只能识别和执行用“0”“1”这样的二进制数所表示的指令,用二进制数表示的指令的集合称之为机器语言。在计算机诞生初期,程序员在纸带上打孔表示1,不打孔表示0,再将纸带输入计算机运算,但在现代无法实现。
2.2 汇编语言
汇编指令是汇编语言的主体。机器指令运用的是“0”“1”的组合,而汇编指令的格式更容易书写和记忆,例如“MOV AX,BX”将寄存器BX的内容发送到AX上。汇编语言程序和硬件相关,不同的处理器汇编指令可能不同。程序员用汇编语言编写程序比较复杂。
2.3 高级语言
目前常用的C/C++、java等都是高级语言,高级语言从人类习惯的语言结构出发,更容易读懂和表达,高级语言与指令或者硬件的相关度低,更多是对数据的运算和控制,通过算法实现具体功能。
高级语言程序需要通过编译器变成汇编程序,然后通过汇编器变成机器代码,最后才能被计算机执行。其中C/C++是编译语言,静态编译,即编译器直接将程序编译成机器码,安装到硬件设备上就能执行。而Java为了实现跨平台的操作,运用虚拟机来调度硬件资源,虚拟机中包含了翻译器或编译器,Java是预编译语言,动态编译,在开发环境中将源码转换成字节码,再由虚拟机中的编译器或解释器转换为机器语言。
3 安卓编译器
Android应用程序基于Java语言,所以都是依靠虚拟机进行编译或解释的。2008年,Android1.0使用的是Dalvik的虚拟机,里面集成了一个解释器,用户每一次打开Android应用程序时,解释器就开始翻译。它的执行方式是一边翻译一边执行,因此其执行效率很低。2010年发布的Android 2.2使用了JIT(Just in Time)即时编译机制,即当Android应用程序运行时,会同时将用户经常使用的功能编译为机器能直接执行的机器码,而不是碰到一句执行一句。当用户使用了不常用的功能时,再让解释器进行翻译。但缺点是不能一劳永逸,每次启动应用程序都要重新编译。2014年发布的Android 5.0,将Dalvik虚拟机换成了性能更好的ART(Android Run Time),同时把AOT (Ahead of Time)编译器替代了JIT。AOT是指应用程序在手机安装时就把代码先编译成机器码,这样就不需要每次打开应用程序的时候重新编译。但其有2个缺点:①占用存储空间,编译后的机器码体积迅速膨胀;②程序安装速度慢。
对于2017年的Android 7.0,Google对其进行了改进,采用AOT+JIT+解释执行的方式,应用程序安装时不执行编译,安装速度快。应用之后,系统收集经常被传输的代码信息,设备空闲时直接把这些代码编译为机器码(AOT)。剩下的部分在运行时通过JIT和解释器实现,用时间换效率,达到一种平衡。但无论如何演变,仍然只是在虚拟机上进行优化,虚拟机+编译器+解释器的结构本身就是一种对硬件资源的占用,Java这样的预编译解释型语言,每执行一行代码,先有解释器解释机器码,然后再去执行。其优点是不同平台只需要换用不同的解释器;缺点是运行效率低下,程序的运行性能仍无法得到最大发挥。
Android编译器演变如表1所示。
表1 Android编译器演变
Android版本1.02.25.07.0 虚拟机DalvikDalvikARTART 编译机制解释器JIT+解释器AOTAOT+ JIT+解释器
Android 1.5系统之后Google允许Java通过JNI(Java Native Interface)Java原生接口去调用一些由C/C++代码开发的so库,来实现和C/C++等代码的互交。两种不同框架的语言相互调用,JNI需要调用硬件资源来做调度,这种机制效率也很低。
当内存资源不足时,C/C++需手动释放内存,而Java可以自动释放内存,Java虚拟机将会不定期自动回收不再被使用的对象,这也是Java语言的重要优点。但同时也造成了一些问题,当内存资源不够时,虚拟机运用GC(Garbage Collection)机制进行内存资源回收,Java虚拟机所有运行的线程将会暂停。虽然这个过程很短暂,但用户是无法准确控制的,如果是性能较差的手机可能还会出现“间歇性”卡顿的现象。
4 方舟编译器初探
据官网介绍,方舟编译器是为支持多种编程语言、多种芯片平台的联合编译、运行而设计的统一编程平台,包含编译器、工具链、运行时等关键部件。从开源框架来看有以下特点。
4.1 彻底摒除了虚拟机
方舟编译器也属于AOT,所采用的机制是在程序编译打包的时候已经将Java代码转换成机器码,将Java原本的动态编译改为静态编译,这样提供给用户的安装文件所包含就已经是机器码了,不需要在用户的手机上进行编译,即使是应用程序安装后首次运行也会非常流畅。
4.2 支持多语言
方舟编译器将同时支持Java和C/C++多种语言,包括混合语言,各种语言实现统一的编译器中间表示(IR),使各种程序语言代码在开发者环境中编译成统一的可直接执行的机器码,具体如图1所示。
图1 多语言支持
4.3 消除卡顿
方舟编译器采用了引用计数法(RC,Reference Counting)来进行内存的实时回收,并且配合使用了专门的消除环算法(消除对象互相引用带来的无法回收问题),来避免GC集中式回收带来的系统卡顿。相比GC,方舟的内存回收是实时的而非集中式的,且不需要暂停应用进程,这样便大大消除了卡顿。
4.4 生成so库
方舟编译器的工作原理:生成的安装包改变了Android原本的apk格式规则,但有可能目前的Android是无法兼容的,但从官网的演示代码来看,输出了so库,so库是C/C++通过Android的 ndk编译之后生成的本地库,是Android系统支持的,形成so库能够保证最后生成的安装包文件和原生的apk文件格式一致;虚拟机的自动回收内存资源的工作也不需启动,“间歇性”卡顿现象消失。
5 结语
从官方发布的内容看,方舟编译器强大,始于安卓,强于安卓,赶超IOS,但是由于目前只开源的框架源码和部分功能演示,所以方舟编译器的具体表现如何还有待考证。既然方舟编译器支持多语言和多种硬件平台,是否会发布一个与AndroidStudio类似的开发平台,也是值得期待的。中国计算机行业最根本的编译器、操作系统、芯片等领域还是比较落后的,而华为是国内为数不多有这个能力,并且愿意投入人力和物力在这几个领域的企业,华为需要的是时间,人们期待着方舟,期待着鸿蒙。
TP314
A
10.15913/j.cnki.kjycx.2019.23.018
2095-6835(2019)23-0047-02
龚宇洁(1984—),女,硕士研究生,研究方向为电子计算机。
2017年武汉市教育局教学研究项目“‘互联网+’背景下《Android应用开发》课程学生自主学习策略研究”(编号:2017162)
〔编辑:张思楠〕