本帖最后由 请称呼我所长 于 2019-8-6 18:46 编辑
好玩的、新鲜的、实用的“搞机资讯”都在这里,和所长一起去“搞ji”吧! -----最in科技所-----
方舟编译器各位机友肯定不陌生。作为华为磨剑10年的创世之作,2019年4月,华为方舟编译器正式面世。今天所长带大家聚焦华为新贵——方舟编译器,这个一发布就引起巨大响动的底层核心技术。它为什么能拥有和世界对话的荣光?它承载着怎样的使命?它能否做到传说中的“出于安卓,胜于iOS”?
1. 机器的“原力觉醒”
这个故事,先从计算机的语言说起。公元8世纪,印度人发明了数字0-9,这种十进制的数学符号让数据存储和处理的效率一日千里,成为人类文明重要的里程碑,奠定了现代数学基础。
还有一种文字系统——“0”和“1”的二进制,是人类文明另外一个重要的里程碑,被广泛应用在现代计算机领域中。此外,我们喜欢的音乐、我们热爱的电影、我们拍摄的照片,今天都是通过这种二进制的数字来进行“重现”,包括记录、存储、传播和分享。
人类通过0和1开启了机器“文明”,从此科学革命的进程就像安装上了“火箭”。
在计算机里,所有的运算转化为最简单的判断和计算,1表示Yes(开),0表示No(关),计算机用0和1不断重复计算。这就是计算机使用“0”和“1”二进制语言的理论基础。
0和1这种极简的语言设计,像给计算机注入了永远在生长的“原力”,带来了无限的可能。与通信领域IP路由理念具有异曲同工,就像“看不见的蒸汽机”,用最简单的理论架构开启了一个全新的伟大产业。
2. 软件王国的“四大明珠”
实际上,在电子计算机诞生之前,程序设计人员都要把程序编排成010101这样的形式,在纸上打孔,再送到机器里去读。因此,当程序员开始在卡片上写这些程序时,人们开始构建程序库。随着时间的推移,大部分的程序渐渐的有了一些规则手册来指导编写。但还是很繁琐,毕竟编写和记忆0和1的各种组合,对于很多人来说相当于是“天书”。
1963年,英国剑桥大学推出了CPL语言,后又推出了简化的BCPL语言。1970年,美国贝尔实验室推出了更加简单的B语言(取BCPL第一个字母),后又简化出了C语言(取BCPL第二个字母)。这是目前世界上最常用的编程语言之一,甚至可以说是第一大编程语言。
C语言之后,诞生了很多著名的语言,包括:
其中,C/C++是编译语言,即在程序员写完程序后,通过编译器直接编译成机器码,安装到相应的硬件设备上即可直接运行。Java/C#是预编译语言,就是需要先在开发者环境中将源代码转换成字节码,然后在设备上运行时再将字节码编译或解释成硬件能听得懂的机器码。将源代码转换成字节码的过程,就叫预编译。
软件王国还有两个很重要的成员,就是操作系统和数据库。1970年,贝尔实验室B语言和C语言的开发者肯·汤普逊和丹尼斯·利奇,开发出了世界第一个通用计算机系统——UNIX。现在大家熟悉的Linux和Mac OS就是类UNIX操作系统。其中Linux可以运行在服务器和其他大型平台之上,如大型计算机和超级计算机。
高级编程语言、编译器、操作系统和数据库,被称为软件王国的“四大明珠”。从上图可以看出,为软件底层贡献核心技术的公司主要来自于欧美。华为通过多年持续的研发投入,让我们终于看到了美国巨头的背影。
3. 编译器的前世今生
如果说计算机是汽车,那么软件就像汽车的操控系统一样,是计算机的血液。编译器则是汽车发动机里最核心的汽油燃烧技术,将软件变成计算机的动力,其编译性能和效率,直接决定了用户的使用体验。目前主流使用的编译器主要有下面几种:
4.安卓的四大命门
所长交待完计算机和软件的发展历程,终于说到正题。安卓系统从2008年1.0到今天的9.0,安卓手机的体验已经今非昔比。为什么仍然还有很多人诟病安卓手机没有iPhone流畅?安卓系统的程序是怎样运行的?下面所长展开阐述一下安卓的四大命门。解决安卓这四大命门,也是华为方舟编译器的使命!
第一个命门 : Java的“虚拟机”
前面提到,Java为了能够实现跨平台操作,便借助虚拟机来调度硬件平台资源。在虚拟机里,还需要集成翻译器或者编译器,来将Java的字节码(即中间代码)解释成机器听得懂的机器语言,或者直接编译成机器直接执行的010101的机器码。
Android 1.0刚发布的时候,使用的是一个叫Dalvik的虚拟机,里面集成了一个解释器,每次用户在安卓手机上运行APP时,就会叫醒这个解释器,来给安卓的硬件解释APP想要干嘛。这就相当于新闻发布会,发言人讲一句自己的母语,然后再由专业翻译将其翻译成外国记者听得懂的语言,效率非常低下,一个小时可能也问不了几个问题。
谷歌意识到这个问题严重拖了安卓手机的后腿,所以通过一年多的努力,在2010年中发布了2.2版本,引入了JIT(Just in Time,即时编译)机制。JIT比较聪明,当用户在安卓手机运行APP时,会同时将用户经常使用的功能编译为机器能直接执行的010101机器码,不用每一句每一句的去翻译。当出现不常用的功能时,再把解释器叫起来翻译。
JIT虽然变聪明了一点,但是每次启动APP都要先编译一次,不能一劳永逸。谷歌在2014年10月推出了Android 5.0版本,将虚拟机从Dalvik替代成ART,同时把JIT的编译器替代成AOT 。AOT相比JIT的好处,就是不用每次打开APP都需要先编译一遍。但是,坏处就是用户安装APP的时间有点长。
Android 7.0又做了一点改进,安装时先不编译中间代码,而是在用户空闲时通过AOT编译器先静态编译。如果AOT还没来得及编译或者不能编译,再叫醒JIT+解释器两个难兄难弟来顶住。这种机制,相当于用时间换空间,既缩短了用户安装APP的等待时间,又将虚拟机里编译器和解释器能做的优化提升到最大效率了。
很多人以为华为方舟编译器就是Android 7.0的ART虚拟机,其实不然。手机上的虚拟机+编译器+解释器本身不仅占用硬件资源,还无法最大发挥软件运行性能。正因如此,绝大部分手机厂商只能无奈的通过简单粗暴提升安卓手机的内存和存储空间,来弥补虚拟机的弊端。这就是安卓的第一个命门,虚拟机先天不足。
第二个命门 : Java的“原罪”——额外的JNI开销
JNI,全称Java Native Interface(Java原生接口),用来和C/C++等代码进行交互。
目前95%的TOP应用都是使用Java和C/C++等多种语言混合开发而成。Java和C/C++属于两种不同架构的语言,各有自己的使用规范。为了APP正常运行,它俩之间需要互通有无,这个互通有无的接口就是JNI。这就意味着手机硬件资源要分配一部分给JNI去做调度。不仅占用了硬件资源,而且这种机制本身就效率较低。
第三个命门 : 代码优化空间有限
安卓虚拟机的编译器受限于手机硬件和代码优化模板单一,代码优化空间有限。编译器包含三个部分。前端Front End,主要负责将源代码翻译成IR;中端的Optimizer主要负责代码优化,将前端翻译过来的IR代码优化得更高效;后端Back End则将优化后的IR编译成101010的机器码。
为了防止生态过于碎片化,安卓只为第三方开放了简单的编译代码优化模板,代码优化空间有限。
第四个命门 :Java现有内存回收机制易造成间歇性卡顿
当手机内存资源不够用的时候,安卓虚拟机就会召唤GC(Garbage Collection)封锁公路,让所有手机运行的Java线程“Stop World”,全部暂停,等待它回收内存空间,避免“交通流量超载”。这个GC机制,无法精确控制和干预,用户也无法把它去掉,所以性能比较差的手机还存在“间歇性”卡顿。 十余年间,通过安卓系统的持续优化,以及内存的不断加持,安卓手机构筑了足够流畅的用户体验。但是安卓的四大命门,如同达摩克利斯之剑,悬在安卓厂商的头上。华为科学家和工程师们,对此持续攻关了十年,只为再造安卓。
5.十年方舟,再造安卓
正如所长所说,华为为此准备了十年。2018年春节前一周,方舟编译器跑通安卓系统所有后台服务,并成功移植到手机。当晚,所有人聚集在实验室的机房中,等待首个开机画面加载成功的神圣时刻。秒针滴答,如同过了一个世纪那么久,屏幕终于点亮。
当P30发布会上“方舟”甫一出现,就在中国软件行业“炸”了锅。一方面,方舟编译器首次在Java领域将虚拟机干掉了,也是软件史上首次将Java/C/C++等混合代码一次编译成机器码直接在手机上运行,彻底告别Java的JNI额外开销,如果说目前最新的安卓系统是和谐号动车,那么经方舟编译的安卓系统便是高铁,是“复兴号”。
另一方面,方舟编译器用空间换性能,直接将编译器的代码优化搬到了开发者环境,不再被手机端的硬件资源所限制,为代码优化提供了无限可能。此外,经测试,新浪微博极速版APP经方舟编译后,操作流畅度提升高达60%。解决安卓的四大命门,出于安卓,胜于安卓,超越iOS,并且全面兼容安卓,这就是华为方舟编译器的使命!
6.生来就是要干掉虚拟机
方舟编译器从立项开始,就是要彻底干掉虚拟机。这在历史上,是从来没有人做过的。这么多年,从来没有人能够干掉虚拟机,说明难度非常之大。比如现在大行其道的安卓ART虚拟机。这些尝试能够提前翻译Java语言里很多的静态语义,但是多数的动态语义,仍然搞不定,还得交给虚拟机。
所谓静态语义,我们可以理解为确定的语言和意思,比如“我是张三”。而动态语义,则需要结合上下文去理解,比如“能穿多少就穿多少”,到底穿多还是穿少,要看是冬天还是夏天了。例如大家熟悉的微博、京东等APP的开屏广告就需要用到动态语义。像编译静态语义一样去编译动态语义,很多知乎大神认为根本就不可能。
方舟编译器通过编译阶段和运行阶段的双向加持,将静态编译动态语义最大的两大难点一一解决:一是设计数据模型,二是如何在运行时高效获得动态信息。这两大难点的突破,让方舟编译器能够将Java代码编译成机器能直接执行的语言。经过华为方舟编译器的APP,再也不需要在手机上编译了,彻底告别了虚拟机,从而带来了媲美甚至超越iOS的安卓体验。
7.代码“万国通”
华为方舟编译器团队基于多个编程语言的深刻理解和大量研发积累,将混合语言破天荒实现了统一的中间表示IR,这就相当于同一个人能够理解全世界的语言,所以我们把这个革命性突破叫做,代码“万国通”。需要在手机上编译了,彻底告别了虚拟机,从而带来了媲美甚至超越iOS的安卓体验。
那么方舟编译器是如何使用统一的IR来表示各种语言呢?
华为方舟编译器团队对IR进行了长达五年的精雕细琢,逐渐摸索出“大脑”里每一条神经、每一个神经元的信号规律,并在此基础上发明了一套核心专利,使得不同语言代码在开发者环境中能够统一编译成同一套可直接执行的机器码,从而彻底消除混合语言互相调用的开销。
8. 给代码装上飞机发动机
除了IR,编译器还有一个非常重要的价值,就是代码优化。华为方舟编译器,直接将代码优化从手机环节搬到了开发者环境,未来还可能搬到云端。利用开发者环境更强大的算力,可以实现更先进和精细的优化算法,来达到更强大的优化效果,在很多特定场景代码优化的提升甚至是颠覆性的。
这相当于给APP在方舟里装上飞机发动机,让你的APP运行如飞!可以想象,未来广大APP开发者使用方舟编译器后,消费者们的体验将达到一个前所未有的高度。这对于整个安卓生态,都是一件前所未有的幸事!
9.Stop World,安卓卡顿再见
方舟的第四个使命,就是解决安卓虚拟机GC内存回收带来的“Stop World”。目前安卓手机内存资源不够用的时候,GC直接叫停所有应用,所以偶尔会遭遇莫名卡顿。方舟编译器采用了引用计数法来进行内存的实时回收。相比GC,方舟的内存回收是实时的而非集中式的,且不需要暂停应用进程,这样便大大消除了卡顿。
软件有一个大家很熟悉的死循环,就是电脑被一个无限循环的运行程序把计算机资源占光。
这种“死循环”在软件中叫“环引用”。为了从机制避免手机内存被环引用“吃掉”,方舟编译器引入annotation的“告警”标示,对基础类的环进行标注。当然,Java程序员也可以对业务代码中的环进行标注。经过丰富的实践验证,方舟这种机制可减少大部分程序中环的出现。
正是因为方舟做到混合语言的统一中间表示和完全静态编译,它干掉了虚拟机,消除了JNI开销,告别了GC内存回收的“间歇性”卡顿,以及其他很多开销。同时,为开发者进行代码优化提供了一个更广阔的舞台。
看完了所长的介绍,你是否了解了方舟编译器的使命?华为很快将全面开源方舟编译器,届时开发者们可以使用方舟编译器作为开发工具,为移动应用生态和体验打开一扇全新的大门。科技的进步,离不开全球无数科学家和工程师的奉献。产业的繁荣,开放是唯一出路! (本帖源自微信公众号:菊厂搞机)
=====THE END=====
今天的科技所到这就结束啦,各位粉粉对今天的主题有什么看法呢,欢迎一起来讨论,只要你的观点能吸引到所长,就有花瓣送上哦!另外各位粉粉需要什么教程,也可以在下方评论哦,万能的所长帮你实现~
|