我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:刘伯温论坛 > 分别编译 >

解读 华为方舟编译器的革命性到底体现在哪里?

归档日期:08-28       文本归类:分别编译      文章编辑:爱尚语录

  随着 2019 华为开发者大会的临近,华为消费者业务 CEO 余承东此前在 P30 国内发布会上宣布

  随着 2019 华为开发者大会的临近,华为消费者业务 CEO 余承东此前在 P30 国内发布会上宣布的 “能够实现 Android 性能革命” 的方舟编译器也即将进入到开源阶段。虽然此前在 4 月份华为已经就方舟编译器进行了介绍,但人们更加关心的是:华为方舟编译器的革命性到底体现在哪里?

  针对这个问题,余承东在 8 月 6 日推荐了一篇由“菊厂搞机”发表的一篇题为《华为新贵!方舟编译器的荣光和使命》的长文,该文对华为方舟编译器的实现原理和背后故事进行了解读——而雷锋网也希望由此提取出关于华为方舟编译器实现 Android 性能革命的诸多要点。

  在目前全世界的多种编程语言中,Android 操作系统采用的是 Java 语言。

  Java 语言是在 1995 年 5 月发布的,它的一个重点特点就是可以跨平台操作,而且需要借助虚拟机机制来解释源代码并调度硬件资源;但同时 Java 是一种预编译语言,需要先在开发者环境中将源代码(Source Code)转换成字节码(Byte Code),然后在设备上运行时再将字节码编译或解释成硬件能听得懂的机器码。

  2、翻译器(将 Java 字节码解释成机器语言)或者编译器(将 Java 字节码编译成机器码)。此处要注意的是,翻译器和编译器是不同的;编译器是把源程序的每一条语句都编译成机器语言并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,因而速度很快;而解释器则是只在执行程序时,才一条一条地解释成机器语言来让计算机执行,因此运行速度不如编译后的程序运行得快。

  而对于 Android 操作系统来说,为了将 Java 字节码变成机器语言,Google 在不同的版本中进行了多样化的尝试,其目的自然是不断推动应用程序的运行速度向前发展;我们来看一下 Android 在不同版本是怎么做的:

  Android 1.0(2008 年):采用一个名为 Dalvik 的虚拟机,并且集成了一个解释器。当 App 运行时,就会调用这个解释器,对代码进行逐句解释,速度很慢。

  Android 2.2(2010 年):引入 JIT(Just In Time)即时编译机制,当 App 运行时,会将用户经常使用的功能编译为机器能直接执行的 010101 机器码,不用一句一句地去翻译。当出现不常用的功能时,再调用解释器来翻译;这样速度加快,但每次启动 App 都要重新编译一次,不能一劳永逸。

  Android 5.0(2014 年 10 月):将虚拟机 Dalvik 换成 ART(Android Run Time),将 JIT 的编译器替换成 AOT(Ahead of Time)。如此,App 在下载后安装到手机上时同时把能编译的代码先编译成机器听得懂的 101010;剩下不太好翻译的代码,就在用户使用时再叫醒解释器来翻译。如此,不用每次打开 App 都需要编译,但安装 App 的时间有点长,而且占用手机空间。

  Android 7.0(2017 年):采用混合编译机制,安装时先不编译中间代码,而是在用户空闲时将能够编译成机器码的那部分代码,通过 AOT 编译器先静态编译了。如果 AOT 还没来得及编译或者不能编译,再调用 JIT+ 解释器。这种机制,相当于用时间换空间,既缩短了用户安装 APP 的等待时间,又将虚拟机里编译器和解释器能做的优化提升到最大效率了。

  可以看到,无论是编译器还是解释器,只是在虚拟机上打补丁;手机上的虚拟机+编译器+解释器本身不仅占用硬件资源,还无法最大发挥软件运行性能。正因如此,所以绝大部分手机厂商只能无奈的通过简单粗暴提升 Android 手机的内存和存储空间,来弥补虚拟机的弊端。

  2、为了与 C/C++ 等代码进行交互,Java 原生接口(Java Native Interface,简称 JNI)应运而生。目前 95% 的TOP应用都是使用 Java 和 C/C++ 等多种语言混合开发而成。Java 和 C/C++ 属于两种不同架构的语言,各有自己的使用规范。为了 APP 正常运行,它俩之间需要互通有无,这个互通有无的接口就是 JNI。在数据访问、函数调用、生命周期维护、异常处理等方面都需要这两种代码互相调用。这就意味着手机硬件资源要分配一部分给 JNI 去做调度——这一机制本身的效率就不高,而且占用了硬件资源。

  3、Android 虚拟机的编译器受限于手机硬件和代码优化模板单一,代码优化空间有限。 编译器包含三个部分:前端 Front End,主要负责将源代码翻译成 IR(Intermediate Representation);中端的 Optimizer 主要负责代码优化,将前端翻译过来的 IR 代码优化得更高效;后端 Back End 则将优化后的 IR 编译成 101010 的机器码——为了防止生态过于碎片化,Android 只为第三方开放了简单的编译代码优化模板,代码优化空间有限。

  4、Java 现有的内存回收机制容易造成 “间歇性” 卡顿。 当手机内存资源不够用的时候,Android 虚拟机就会召唤 GC(Garbage Collection,垃圾回收) 让所有手机运行的 Java 线程全部暂停,等待它回收内存空间,避免过载超载。这个 GC 机制,无法精确控制和干预,用户也无法把它去掉,所以性能比较差的手机还存在 “间歇性” 卡顿。

  在回答这个问题之前,先看一下华为从事方舟编译器工作的时间线G 基础技术研究的同时,开始创建编译组,第一批海内外研究人员加入。

  2013 年,华为推出面向基站领域的自研编译器 HCC,并正式提出编译器框架构想。

  华为所谓的 “方舟编译器” 与其说是一个编译器,不如说是一个编译运行系统;这个系统的运行需要开发环境和终端(也就是智能手机)的配合

  ,其目的是绕过 Android 操作系统中 App 的运行所必须依赖的虚拟机,将 Java/C/C++ 等混合代码一次编译成机器码直接在手机上运行,彻底告别 Java 的 JNI 额外开销,也彻底告别了虚拟机的 GC 内存回收带来的应用进程掉线——从而最终实现 Android 操作系统的流畅度。

  就目前的情况来看,Java 编译成机器码的过程中,要面临的难题是 Java 中的动态语义(与之对应的是静态语义,它是通过提前翻译能够解决的),静态语义指的是确定的语言和意思,而动态语义指的是需要结合上下文来理解的内容——这其中,如果要像编译静态语义一样去编译动态语义,很多知乎大神认为是根本就不可能的。

  具体来说,方舟编译器通过编译阶段和运行阶段的双向加持,将静态编译动态语义最大的两大难点解决:一是设计数据模型,二是如何在运行时高效获得动态信息。方舟编译器团队基本遍历了 Java 的动态语义,进行了大规模的数据建模。同时,大大提高了编译时动态语义分析的精度,特别是涉及跨语言调用时;另外,华为设计了一套具有核心专利的动态语义匹配机制,有效降低了运行时动态语义的开销。

  由此,方舟编译器能够将 Java 代码编译成机器能直接执行的语言。华为方面表示,经过华为方舟编译器的 App,再也不需要在手机上编译了,彻底告别了虚拟机,从而带来了媲美甚至超越 iOS 的 Android 体验。

  华为方舟编译器团队对 IR 进行了长达五年的精雕细琢,逐渐摸索出 “大脑” 里每一条神经、每一个神经元的信号规律,并在此基础上发明了一套核心专利,使得不同语言代码在开发者环境中能够统一编译成同一套可直接执行的机器码,从而彻底消除了混合语言互相调用的开销。

  也就是说华为方舟编译器可以将混合语言实现统一的中间表示 IR,这就相当于同一个人能够理解全世界的语言——当然,这背后是华为方舟编译器团队基于多个编程语言的深刻理解和大量研发积累。

  方舟编译器采用了引用计数法(RC,Reference Counting)来进行内存的实时回收,并且配合使用了专门的消除环算法(消除对象互相引用带来的无法回收问题),来避免 GC 集中式回收带来的系统卡顿。

  另外,软件有一个大家都很熟悉的死循环,就是电脑被一个无限循环的运行程序把计算机资源占光。这种 “死循环” 在软件中叫 “环引用”。为了从机制避免手机内存被环引用 “吃掉”,方舟编译器引入 annotation 的“告警”标示,对基础类的环进行标注。

  当然,Java 程序员也可以对业务代码中的环进行标注。经过丰富的实践验证,方舟这种机制可以减少大部分程序中环的出现。另外一方面,方舟编译器在运行状态下引入了高效的环回收机制,允许有选择的智能回收某个 APP 的内存占用,这对传统的环回收算法是一个改进。

  这其中的核心创新点是混合语言的统一中间表示和完全静态编译,但更重要的是华为在解决 Android 操作系统 App 运行问题的崭新思路,以及为了实现这种思路而敢于大力投入的勇气。

  正如雷锋网所言,方舟本质上不仅仅是一个编译器,而是一个编译系统,它需要通过用户终端和开发者的共同支持。对于华为手机用户来说,华为在手机终端中已经用方舟编译器替代了 Android system-server 的所有后台服务,这一项就已经足够让华为 EMUI 比其他 Android 系统更快一步——根据华为官方测试,方舟编译器提升手机系统操作流畅度高达 24%,系统响应性能提升 44%。

本文链接:http://saltstudios.net/fenbiebianyi/853.html