说说 方舟编译器

简介: 说说 方舟编译器

image.png

华为继去年推出黑科技 GPU Turbo 之后,今年再次扔出了一枚重磅炸弹, 安卓性能革命,华为方舟编译器,号称解决安卓程序 “边解释边执行” 的低效,全程执行机器码高效运行程序。架构级优化,显著提升性能。系统操作流畅度提升 24%,系统响应提升 44%,三方应用操作流畅度提升 60%,并承诺向业界开源。敢于开源的话,这个数据应该没有水分。大家在网上应该也看到了 P30 Pro 吊打 S10 的视频。


解决安卓程序 “边解释边执行” 的低效,什么是边解释边执行?也就是说,Android 是如何执行 Apk 中的代码的?这得从机器码说起。


机器码


不论是低级语言,如汇编,还是如今广泛使用的各种高级语言,Java,C++ 等,对于 CPU 来说,全部都是天书。它能认识的只有二进制的机器码。当然,机器码对你来说,也是天书。那你应该如何指挥 CPU 运行你的程序呢?这个时候,你们之间就需要一个翻译,将你的代码翻译成机器码给 CPU,它就知道该如何执行了。面对不同的终端,翻译内容也不一样,你一个只知道 x86 指令集的去翻译 arm 的,肯定翻译不出来,就好似拿着本英语字典去翻译日语。翻译也有工具,下面说说几种常见的翻译工具:


汇编器

将汇编代码直接翻译成机器码。由于汇编代码一般和机器码都是一一对应的,所以它的速度非常快。只是汇编语言,你懂的,可读性差, 用起来难,用来写大型程序对于普通开发者基本是不现实的。


编译器

编译器将我们平常开发用的高级语言,例如 Java/C++ 等,翻译成机器码供 CPU 使用。这种编译很慢,但是执行起来会很快。


解释器

程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次。因此效率比较低。可以想象这种运行方式就慢了很多。 典型的解释型语言,php/js/python 等。


JAVA 代码是如何执行的 ?


Java 程序的执行依赖于 Java 虚拟机(JVM),JVM 能直接识别的叫做字节码。Java 代码经过编译会生成 Class 文件,即字节码文件,再交由 JVM 处理。而 JVM 又是怎么执行 Class 文件的呢?这里以 HotSpot 为例,Class 文件被虚拟机加载后会存放在方法区,实际运行时,虚拟机会执行方法区中的代码。


将字节码翻译成机器码的工作自然就由 JVM 来承担了。在 HotSpot 中,有几种翻译形式。

  • 解释执行

逐条将字节码翻译成机器码并执行

  • 即时编译(Just-in-time ,JIT)

将一个方法中包含的所有字节码编译成机器码后再执行。

前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两 者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。


Android 代码是如何执行的 ?


开发 Android 目前用的最多的还是 Java,即使不是 Java,也是 JVM 语言。Android 工程中的 java 源文件经过编译也是生成 Class 文件,最后被打包成 DEX 字节码文件,负责将 DEX 字节码翻译成机器码的是 Dalvik 或者 Art。


在 Android 5.0 之前,还是 Dalvik 的天下。Dalvik 是解释执行加上 JIT,每次app运行的时候,它动态的将一部分 Dalvik 字节码 解释为机器码。随着 App 的运行,更多的字节码被编译和缓存。因为 JIT 只编译了一部分代码,它具有更小的内存占用和更少的设备物理空间占用。但是,边解释边执行,效率低下,这也是后来 Dalvik 遭到抛弃的原因。


从 Android 4.4 开始,Android 引入了 Art,到 Android 5.0,Art 正式代替了 Dalvik。Art 使用的是 AOT(Ahead of Time)的编译方式,即在应用的安装过程中,就将所有的 Dex 字节码翻译成机器码存储在设备空间中,完全抛弃了 JIT,带来的好处是显而易见的。

  • Apps 运行的更快,因为 DEX 字节码的解释在安装过程中已经完成,直接运行机器码
  • 减少了应用的启动时间,因为本地代码可以直接执行。
  • 节省电量消耗,不需要再去一行一行的解释字节码。
  • 增强了垃圾回收。
  • 增强了开发者工具。


直接运行机器码,恩,等等,这不就是方舟编译器做的事情吗?答案肯定是否定的,否则它因为完全没有存在的必要了。事实上,这种完全基于 AOT 的模式也已经被       Android 抛弃了。如果你用过 5.0 或者 6.0 的安卓机,你一定不会忘记安装应用带来的漫长等待。由于需要在安装期间翻译字节码,所以安装过程会很长,尤其对 一些大型应用来说。另外,安装过程中翻译出来的机器码也占用了更大的机身存储空间。


Android 7.0,Android 又加入了 JIT,一个具备代码分析功能的即时 (JIT) 编译器。事实上,根据二八定律,经常运行的热点代码可能只占 20%,甚至更少,我们没有必要通过 AOT 提前将所有字节码都翻译成机器码。安装过程中放弃 AOT,加快安装速度,所以初次使用时得解释执行。当你在使用应用时,JIT 就开始分析代码了,在合适的时候将字节码翻译成机器码,在 Android 应用运行时持续提高其性能。另外,设备空闲的时候,AOT 就发挥作用了,它会将热点代码翻译成机器码并保存下来,进一步提高运行效率。这么看下来,现在的 Android 是 解释执行 、JIT、AOT 同时存在的。下面这张官网的图片很好的说明了Art 下的 JIT 架构.

image.png

关于解释器,高版本中的 Android 实现也不再那么孱弱了,根据官网相关介绍:

通过引入 Mterp(一种解释器,具有以汇编语言编写的核心提取/解码/解释机制),Android 7.0 版本中的解释器性能得以显著提升。Mterp 模仿了快速 Dalvik 解释器,并支持 arm、arm64、x86、x86_64、mips 和 mips64。对于计算代码而言,ART 的 Mterp 大致相当于 Dalvik 的快速解释器。 不过,有时候,它的速度可能会显著变慢,甚至急剧变慢:

  • 调用性能。
  • 字符串操作和 Dalvik 中其他被视为内嵌函数的高频用户方法。
  • 堆栈内存使用量较高。

Android 8.0 解决了这些问题。


说了这么多,无非是安装速度,空间占用,运行速度的平衡,目前 Android 应该已经做得很好了,但仍然存在不少诟病。


现在可以确定的是,方舟编译器绝对不可能是 完全 AOT。PPT 中最后一句话是 “希望 APP 厂商尽快使用” ,并不是手机厂商,所以不排除方舟编译器可以直接将 Apk ,或者说 Apk 中的 DEX 打包成机器码格式。但由于机器码并不是平台兼容的,所以并不能确定方舟编译器是否必须要绑定 EMUI。其实说到底,这一切都应该是为了华为的新手机系统作铺垫。华为的野心之大,以及其极其超前的技术储备,相信一个完整华为生态已经离我们不远了。

编译器叫方舟,新系统干脆就叫 诺亚 吧!



相关文章
|
23天前
|
算法 编译器 C语言
《C 语言预处理指令:代码编译前的 “魔法棒”》
《C 语言预处理指令:代码编译前的 “魔法棒”》介绍了 C 语言中预处理指令的作用和使用方法,如宏定义、文件包含等,是编程初学者了解代码编译前处理过程的必备指南。
59 12
|
6月前
|
Rust 自然语言处理 安全
【Rust日报】用 Rust 从头实现一个 C 编译器
【6月更文挑战第9天】使用 Rust 实现 C 编译器的挑战性项目,利用 Rust 的内存安全和高性能优势。涉及词法分析、语法分析等步骤,示例代码展示简单的词法分析过程。实际实现需处理更多复杂环节,如抽象语法树构建和代码生成。此项目能深化对编译器原理的理解,提升 Rust 技能,并有望推动更多高质量 Rust 编译器的诞生。
141 7
|
1月前
|
缓存 编译器 API
C# 一分钟浅谈:Roslyn 编译器平台介绍
【10月更文挑战第27天】Roslyn 是 Microsoft 开发的开源编译器平台,支持 C# 和 VB.NET。它将编译过程分解为多个阶段,并提供丰富的 API 供开发者分析、生成和修改代码。本文介绍了 Roslyn 的基本概念、安装配置、基础示例和高级应用,帮助开发者更好地理解和使用这一强大工具。
49 0
|
3月前
|
Rust 安全 前端开发
30天拿下Rust之图形编程
30天拿下Rust之图形编程
50 0
|
6月前
|
程序员 Linux 开发工具
老程序员分享:OpenCPN介绍及编译
老程序员分享:OpenCPN介绍及编译
228 4
|
6月前
|
存储 安全 算法
JAVA泛型:编译时的“守护神”,你值得拥有!
【6月更文挑战第28天】Java泛型,自Java 5起,是编程的得力助手。它引入类型参数,提升代码安全性和重用性。通过泛型,编译时即检查类型,减少运行时错误,简化类型转换,如示例中泛型ArrayList确保只存String。泛型,是代码的忠诚卫士,助力编写更健壮、易读的Java代码。
29 0
|
Dart Java 编译器
Android编译器及编译工具之编译器
习惯了IDE以及各种现成的编译工具为我们提供便捷的编译方式,我们很少会操心编译工具的编译过程和原理,但是工具越高级,隐藏的细节就越多,这样编译遇到问题时我们难以定位,遇到复杂的项目(尤其跨平台项目难以用ide)时不知如何下手。所以准备写两篇关于编译器和编译工具的文章。本文先来介绍编译工具。
216 0
|
7月前
|
Rust 前端开发 Java
第2章 | Rust 导览
第2章 | Rust 导览
94 0
|
前端开发 C语言 iOS开发
基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了
跟学院派的厚书给大家的印象不同,其实用LLVM写个简单的编译器是件容易的事情,因为大部分事情LLVM都替我们做了。
8343 0
|
自然语言处理 前端开发 编译器
前端学编译原理(一):编译引论(下)
前端学编译原理(一):编译引论(下)
282 0