谈一谈 OpenHarmony 的方舟编译体系
Posted 特立独行的猫a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈一谈 OpenHarmony 的方舟编译体系相关的知识,希望对你有一定的参考价值。
OpenHarmony 目前主推的应用开发语言是js,谈到javascript多数人想当然的认为不适合用在单片机或嵌入式上,它是脚本语言且还是解释执行的,效率肯定不会高,当然这是传统意义上的偏见。
早前js仅在web浏览器上用的时候确实是这样的。
但自从出现了V8和nodejs, js逐渐的在MVVM前端,移动端H5和后端上都焕发了第二春。微软针对脚本语言的类型不安全也创造发明了typescript,可见重视程度不一般,基于此还创造了很流行的vscode编辑器。不过ts它最终还是先编译成了js,只是写法上更规范和安全。 谷歌的V8引擎则更厉害,V8更加直接的将抽象语法树通过JIT技术转换成本地代码,放弃了在字节码阶段可以进行的一些性能优化,但保证了执行速度。源代码-→抽象语法树-→字节码-→JIT-→本地代码(V8引擎没有中间字节码)。
因此js造已没有传统意义上认为的低性能了。
方舟JS运行时组件
方舟JS运行时(ARK JavaScript Runtime)是OpenHarmony上JS应用使用的运行时。包含JS对象的分配器以及垃圾回收器(GC)、符合ECMAScript规范的标准库、用于运行ARK前端组件生成的方舟字节码(ARK Bytecode,abc)的解释器、用于存储隐藏类的内联缓存、方舟JS运行时对外的函数接口(AFFI)等模块。
下面介绍下方舟编译器的故事。
之前只知道大名鼎鼎的GCC和Clang编译器,想不到我们也有这么强大的编译器。这值得我们自豪,更值得好好学习和推广使用。
安卓系统使用Java作为编程语言,易于开发,但是不会将代码直接编译成机器语言,程序运行时有相当一部分代码还需要通过手机上的虚拟机临时同步编译,影响程序执行的效率。华为方舟编译器采取了静态编译的方式,是首个取代了安卓虚拟机模式的静态编译器。android7.0之后的每个系统版本虽然仍然有一些改变,但基本都是在AOT+JIT+解释执行之间进行动态调整,以找到一个更好的平衡点。可是制约Android运行效率最关键的虚拟机这个点,Google却一直都无法解决。
方舟编译器直接干掉了虚拟机,改变了系统及应用的编译和运行机制,直接将高级语言编译成机器码,让手机能直接听懂“高级语言”,消除了虚拟机动态编译的额外开销,提升了手机运行效率。同时,方舟编译器还能够理解程序特征、使用适合的指令来执行程序,因此能够极大程度地发挥出芯片的能力。
方舟编译器采用全程执行机器码高效运行程序,架构进一步得到优化,可供开发者在开发环境一次性的将高级语言编译为机器码,手机安装应用程序后可全速运行程序,带来效率上的极大提升。根据华为实验室的测试数据,EMUI 9.1在仅仅对系统组件System Server应用了华为方舟编译器后,就带来了系统操作流畅度提升24%,系统响应性能提升44%。
目前,方舟编译器聚焦在 Java 代码性能上,未来,方舟编译器将覆盖多种编程语言(包括 C/C++、JS 等),多种芯片架构(包括CPU、GPU、IPU等),覆盖更广的业务场景。
方舟编译器的诞生经历过很长的过程,是一帮满腔热血的工程师在华为大平台之上经过多年的酝酿和磨砺,一步一步发展到今天,是必然的产物。
2009年下半年开始,第一批编译器工程师加入了位于硅谷的华为美研所,从此开始了华为自研编译器及工具链的历史。初创时期团队人员少,一个巴掌数得过来,但是幸运的是,这个团队经过十来年的积淀,留下了一批华人编译器专家的精华。他们平均从事编译器相关行业20+年。相应的平均年龄40+ 。 作为IT行业的研发人员,我认为这个年龄正是人生的精华,对技术的理解最透彻、精纯。同样幸运的是,华为对基础技术的持续投入,在国内也孕育了一批高达数百人的编译、虚拟机的相关队伍。里面聚集了国内最顶尖的人才。可以说,中国做编译和虚拟机的,有四分之一在华为。
编译器团队的业务从零起步,经历的产品包括多核芯片仿真、基于GDB的调试器、GCC和LLVM基础上的编译器设计,为公司主航道提供了大量的工具链,也创造了很多性能优化的奇迹。可是我一直认为,最大的收获在于培养了大量的人才 。
在经历过这些产品之后,我们感觉到华为内部纷繁复杂的产品需求,应该需要一套自主的软件编程体系来支撑。单纯凭借开源的零散的软件来定制不同的业务需求,效率低下,而且不论是对编译/虚拟机等系统软件还是应用软件团队来说,都没有积累,是很大的浪费。还有一个重要因素,我们从不同的国际大公司聚拢在一起,对这个行业非常了解,很清楚像华为这样的大公司拥有自己的编程体系是多么的重要。我们都非常渴望做这个事情。
最终促使我们下决心的是一个设计编程语言的项目。它的需求是,有没有可能开发一种新的高级语言,类似matlab,同时又能够发挥DSP的硬件能力。传统DSP软件的开发严重依赖于类似汇编的intrinsic,当芯片换代时,这样的软件不得不重新设计和实现。因此,这里很直观的就提出新语言的需求,同时兼顾产能和性能。这就是我们的高级语言Cm的诞生。这是一个在C基础之上融合了类似matlab数据类型和操作的语言。为了追求性能,大量的优化需要在高级IR就开始,即在语法树上进行彻底优化。工作的重点集中在前端,必须对语法树进行深入改造。
GCC没有被我们选中,因为它的前端过于晦涩,需要依赖lex/yacc这类工具自动生成一些代码,这些代码很难用人工去理解,而新语言的开发需要频繁的改动前端。Clang的前端是手写的,非常方便阅读,因此我们就以此为基础进行Cm的设计和实现。Cm取得了巨大的成功。但是,暴露出的问题是,在别人的开源编译器上进行深入的改造,效率太低。有很多具体问题,这里不展开。
至此,那个自主编程体系的问题又进入我们脑海,挥之不去。首先,从纯技术角度来看,华为的业务从最初的CT发展到今天的ICT,编译器工程师面对的芯片从DSP,CPU,GPU到NPU,面对的计算类型和数据访问类型种类繁多,编译器要适配的优化和实现也种类繁多,在各种差异存在的同时又有共性存在。依靠开源的项目实现上述目标,几乎是不可能的,或者说效率是非常低下的。最大的原因在于每个改动尤其是IR以及基础优化的改动,在他人的项目基础之上是很难顺利完成的。其次,从公司的业务来看,华为内部庞大的软件开发队伍以及无数的软件项目,其实是存在很多共性的,一个略微通用的软件开发全栈,从编程语言开始往下直至内核,对于多数项目是有很大收益的,特别在版本维护、演进和优化上。
基于上述现实,我们一直在思考的是,应该有一个自主设计的中间语言,也就是编译器的IR,作为一切软件编译和运行的基础。从而避免在舶来品上进行基础性的改动带来的痛苦,也不需要考虑是否跟随舶来品演进的问题,从而制定自己的技术路线。我个人坚定认为,华为庞大的软件开发体量,迫使我们必须有自主控制独立演进的软件编译分析框架。在此,我们要求这个IR具有很强的伸缩性,能够消化多数常见的语言特性,动态的或者静态(当然,很可能一下子达不到这个要求,但我愿意也能够大幅修改)。在此基础上,编译器的输出应该具有多样性,既可以直接编译成binary,也可以不同层次的IR输出,即以中间代码形式打包,类似Java的字节码。既可以直接送给硬件,也可以中间码进行多种格式的分发。下面这张图体现了我们的意思。
基于此,走自主研发的道路是无法回避的,特别是当前的GCC、LLVM和Open64等IR的设计是没有考虑Java这类语言的特性,包括对象模型以及各种动态特性的描述,与其在他人基础上不停打补丁,不如从头开始设计一个全新理念的IR。这也就是上图中红色的Maple IR。 对于技术人员来说,拥有一个每个细胞都具备自己基因的编译器,是多么惬意的事情。这也是大家的一点技术情节。
方舟编译器原先的名字叫MAPLE(Multiple Architecture Programming Language & Environment),这也是吻合了我们上图的意思。在开源的代码中可以看到很多maple字眼,以及文件的后缀名为.mpl以及.mplt等。MapleIR是重新设计的,跟传统编译器最大的区别在于我们在IR中引入对象的概念,也引入异常处理、同步操作等,因此,它能表达的语义比LLVM和GCC更贴近高级语言且囊括了语言的动态特性。
从上图的描述可以看出,方舟编译器是会输出中间码格式的软件包,中间码是平台无关的。这意味着未来的规划中,我们能够服务于一个分布式、多设备的系统,各设备接收的软件包可以是二进制或者中间码格式。根据设备的能力大小,中间码所包含的信息可以不同。为了实现这个能力,方舟引擎应运而生。这是针对中间码的执行引擎,类似于Java虚拟机。所以一个设备既可以采用直接运行机器码,也可以采用方舟引擎运行中间码。不同于Java虚拟机的是两个方面。一是,方舟引擎输入的Maple IR,这是瞄准多语言的,因此,它比Java字节码的表达范围大了很多。只要能编译成Maple IR,引擎就可以执行。二是,方舟引擎未来要包含仿真能力,也就是说,开发人员在没有实际硬件的条件下,可以仿真一些设备并运行方舟软件。
方舟最早的产品可以追溯到2016年,是JavaScript程序的编译器以及虚拟机,代号为MapleJS。它的目标设备是IoT。配合华为的LiteOS,可以支撑多数的IoT小设备。MapleJS的整体内存消耗在十几KB级别,好于三星的JerryScript。
最近火热的方舟编译器的产品是针对安卓系统下面的Java程序的静态编译(原来代号叫MapleJava)。把Java代码直接编译成机器码,所有的动态语义都通过静态方法来解决。这样的话,Java虚拟机就不用存在了。在安卓系统中,ART(Android Runtime)也不需要了。最常见的卡顿原因,即GC,是通过Reference Counting解决(环引用通过一个按需触发的backup GC搞定,触发频率低到可以忽略不计)。这也是方舟取得流畅度提升的一个主要原因。综合来讲,做静态编译的最强大的地方在于看到更多的程序信息,这其实是为我们将来更宏伟的计划做准备。大家常见的虚拟机JIT编译可以得到profiling信息的优点,在静态编译通过训练一样可以获得,只是两者在信息类型和数据量上各有千秋。
前面图中描述的MapleIR,其核心设计思想是能够兼容常见的几种语言。这个要求背后隐藏的一个长远的设想就是消除跨语言的障碍。举个例子,在Java编程中如果想调用C库,则必须通过JNI机制实现。这个实现的成本是很高的,因为两种不同语言的数据类型、调用约定完全不同,又牵涉到跨语言的异常传播和内存管理,不得不通过虚拟机进行昂贵的处理,效率十分低下。如果能够把两种语言都翻译到MapleIR,在IR上进行数据类型的融合,并在相当大程度上实现调用约定的统一,那么则可以极大的提高效率。我们把这个计划称为“拆墙行动” 。在拆墙行动基础之上,在我们长远的构思中是要做全程序优化的,这是一个跨语言的全程序优化,是对我们自己的巨大挑战。
显然,我们的理想不是做编译器,而是做软件开发系统。这是一个相当大的范围,可以理解为软件开发的生态。我们今天在做的每一件事情,包括Java静态编译,都是为这个目标做准备。它的未来已经着眼于建立完整的软件开发体系。在这整个生态中不得不提的就是编程语言和编程框架。软件开发人员看到的就是编程语言和相关框架,因此,这是生态的入口,方舟的未来必然在语言上要尝试,即使失败也要做。基于此,一个强大的具有相对自动适配能力的编译器前端是必须的。这个前端最大的特点必须是能够最大程度上的自动化,降低语言设计过程中的各种反复带来的开发成本。
除此之外,大量的基于一致的IR的开发工具,包括调试、调优等,必定会应运而生,为此,我们愿意和业界的共同爱好者一起努力,构建一个完整的方舟体系,在编程语言、编译、分布式异构编程框架、分布式运行系统等多个领域奠定基础。
OpenHarmony上的js,得益于方舟编译器的神威相助,自然性能也是提高了一大截。可以直接编译为机器指令执行,不需要经过解释器和虚拟机执行。且它的这套JS UI框架是基于ACE架构模型的,系统UI和各种api调用,直接调的是底层的C++接口,效率当然没问题。
了解一下ACE框架:
Adaptive Communication Environment(自适配通信环境),简称ACE。为一个以C++的Template技术所做成的开放源代码的可跨平台的网络应用程序的程序库套件。
ACE自适配通信环境(ADAPTIVE Communication Environment)是可自由使用、开放源码的面向对象(OO)框架(framework),它实现了许多用于并发通信软件的核心模式。ACE提供了一组丰富的可重用C++包装外观(wrapper facade)和框架组件,可跨多种平台完成通用的通信软件任务,其中包括:事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息路由、分布式服务动态(重)配置、并发执行和同步,等等。
ACE的目标用户是高性能和实时通信服务和应用的开发者。它简化了使用进程间通信、事件多路分离、显式动态链接和并发的OO网络应用和服务的开发。此外,通过服务在运行时与应用的动态链接,ACE使系统的配置和重配置得以自动化。
下面是ACE的体系结构图:
从这个图中,可以很明显的看出,ACE框架的大致轮廓。
从底层往上,依次是C风格的OS适配层,也就是对不同的操作系统底层调用的封装;
上一层是C++的封装类,就是把各种系统调用和系统对象封装成C++类对象;
再往上就是框架层,主要就是Reactor, Acceptor, Connector和Proactor。
在上面就是ACE提供的一些服务组件。
有人会说js不是有一种鸭子模型的用法,编译时怎么知道类型呢,只能解释执行吧。这里有个限定是OpenHarmony上的js只支持ES2015标准和严格模式(use strict),也就是说把之前那种js宽泛的用法给拒了,其实这是好事。js语法不断进化,越走越规范了,早已不是传统脚本语言的范畴了。
OpenHarmony 是真正意义上的面向未来、万物互联的全场景操作系统。
想象下未来任何设备都可以发挥出自己独特的能力,且只需各自发挥自己擅长的能力即可,相互之间可以快速连接、能力互助、资源共享。不需要装app也不需要繁琐的操作,即便个别硬件性能不好,只要搭载鸿蒙都是可以轻松连接使用,不会占用太多的性能,这体验多让人兴奋。音响效果好,里面没歌曲操控不方便,手机一滑动用音响放歌曲。手机编辑不方便,手指一划动,轮转到电脑上办公。电影正在在手机上观看,直接轮动到电视上全家观看,这些在华为的产品上都已是现实。华为的创新力,在国内真可谓称得上是No1。单凭OpenHarmony 的软总线技术这一创新,相信就会有更多美好的场景体验在路上。
最后推荐下这一优秀的系统,希望更多人加入openharmony的队伍共同丰富下生态。当前还不太完善,比如开发板太少,甚至没有旗舰版能跑完整openharmony3.0的全部功能。我觉得这是openharmony目前最大的痛点,但未来可期。
Openharmony的一些亮点:
分布式:基于软总线的跨终端无缝体验
鸿蒙OS的“分布式OS架构”和“分布式软总线技术”通过公共通信平台、分布式数据管理、分布式能力调度和虚拟外设四大能力,使开发者能够聚焦自身业务逻辑,像开发同一终端一样开发跨终端分布式应用,也使最终消费者享受到强大的跨终端业务协同能力为各使用场景带来的无缝体验。
分布式软总线:
是多种终端设备的统一基座,为设备之间的互联互通提供了统一的分布式通信能力,能够快速发现并连接设备,高效地分发任务和传输数据。
分布式数据管理:
分布式数据管理基于分布式软总线的能力,实现应用程序数据和用户数据的分布式管理。用户数据不再与单一物理设备绑定,业务逻辑与数据存储分离,应用跨设备运行时数据无缝衔接,为打造一致、流畅的用户体验创造了基础条件。
分布式任务调度:
分布式任务调度基于分布式软总线、分布式数据管理、分布式Profile 等技术特性,构建统一的分布式服务管理(发现、同步、注册、调用)机制,支持对跨设备的应用进行远程启动、远程调用、远程连接以及迁移等操作,能够根据不同设备的能力、位置、业务运行状态、资源使用情况,以及用户的习惯和意图,选择合适的设备运行分布式任务。
鸿蒙OS将N个设备组合成1个“超级终端”,硬件互助、资源共享,根据个人需求自由调用。华为消费者业务软件部总裁王成录在鸿蒙OS 2及华为全场景新品发布会上表示,“超级终端”在控制中心中提供了手机与PC、平板、音箱等各个设备的无线连接组合,只需要手指将不同设备的图标轻轻滑动到一起即可实现深度连接,为万物互联时代提供了一种全新的连接、操作方式。
安卓和iOS受限于较大的系统体积,难以在小型内存终端上广泛搭载。
鸿蒙OS定位于面向未来的IoT操作系统,为满足万物互联的全场景智慧时代对OS提出的新要求,实现模块化解耦,根据不同设备的硬件能力与需求组合拼装,在不同的设备上都可以弹性部署。同时,鸿蒙OS通过分布式软总线连接不同终端,让应用轻松调用其他终端的硬件外设能力,为消费者带来跨终端无缝协同体验。
生态共享:让开发者“书同文”,让终端“车同轨”
鸿蒙OS配备面向多终端开发的统一 IDE(集成开发工具),可支撑开发者实现一次开发、多端部署,最终实现跨终端生态共享。跨终端生态将打破各终端被不同系统隔离的“孤岛效应”,将大大降低用户在不同终端间数据传输的门槛,并提升使用效率与便捷性。
鸿蒙 2.0 全面开源,助力硬件厂商与开发者
2020年,华为面向开发者发布鸿蒙2.0的Beta版本,并宣布将鸿蒙OS的源代码捐赠给开放原子开源基金会进行开源孵化。根据华为公布的开源路标,2021年10月以后,鸿蒙将面向4GB以上所有设备开源。
面向硬件生产厂商:华为开放源代码、SDK、开发板/模组、HUAWEI DevEco等平台和工具链,为鸿蒙OS设备提供一站式开发环境。
面向应用开发者:鸿蒙借助分布式软总线技术,为开发者提供包括编程框架、APIs、DevEco、方舟编译器等一系列平台及工具链,帮助开发者快速开发基于鸿蒙系统的跨设备、全场景的应用软件。
实现合作伙伴快速、低成本连接用户:
合作伙伴的智能硬件产品能够基于鸿蒙OS,实现极简配网、万能卡片、极简交互、硬件互助等能力。用户手机一碰即可将智能设备联网,无需安装APP也能随时控制,有效解决了设备智能特性使用率低等难题。
各合作厂商产品可融合成为“超级终端”:
基于鸿蒙OS,各合作品牌厂商之间相互分离的设备可以根据消费者不同的需求、不同的场景,组合不同设备的软硬件能力,融合成“超级终端”。
引用:
TypeScript中文网 · TypeScript——JavaScript的超集
鸿蒙OS:万物互联,方舟Compiler - 吴建明wujianming - 博客园
ACE框架简介以及一个基于ACE的C/S服务程序实例_拥抱变化-CSDN博客_ace框架
以上是关于谈一谈 OpenHarmony 的方舟编译体系的主要内容,如果未能解决你的问题,请参考以下文章