说说 方舟编译器

2024-02-17 21:32
文章标签 编译器 方舟

本文主要是介绍说说 方舟编译器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

华为继去年推出黑科技 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 架构.

关于解释器,高版本中的 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。其实说到底,这一切都应该是为了华为的新手机系统作铺垫。华为的野心之大,以及其极其超前的技术储备,相信一个完整华为生态已经离我们不远了。

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

文章首发于微信公众号: 秉心说 , 专注 Java 、 Android 原创知识分享,LeetCode 题解,欢迎扫码关注!

这篇关于说说 方舟编译器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/719043

相关文章

【linux学习指南】Linux编译器 gcc和g++使用

文章目录 📝前言🌠 gcc如何完成🌉预处理(进行宏替换) 🌠编译(生成汇编)🌉汇编(生成机器可识别代码) 🌠链接(生成可执行文件或库文件)🌉函数库 🌠gcc选项🚩总结 📝前言 预处理(进行宏替换)编译(生成汇编)汇编(生成机器可识别代码)连接(生成可执行文件或库文件) 🌠 gcc如何完成 格式 :gcc [选项] 要编译的文件 [选项] [目标文

C++入门(05-2)从命令行执行C++编译器_GCC

文章目录 GCC编译器1. 下载MinGW-w64,安装(不推荐)2. 使用MSYS2安装MinGW-w64(推荐)2.1 安装MSYS22.2 初始化和更新2.3 安装MinGW-w64编译器2.3 在MSYS2 Shell中导航到代码目录2.4 使用 g++ 编译2.5 运行可执行文件 GCC编译器 GCC(GNU Compiler Collection)是一个开源编译器集

gcc 编译器对 sqrt 未定义的引用

man sqrt  Link with -lm. gcc -o test test.c -lm 原因:缺少某个库,用 -l 参数将库加入。Linux的库命名是一致的, 一般为 libxxx.so, 或 libxxx.a, libxxx.la, 要链接某个库就用   -lxxx,去掉头 lib 及 "." 后面的 so, la, a 等即可。 常见的库链接方法为

C++入门(05)从命令行执行C++编译器_MSVC

文章目录 1.C++ 编译器2. 常用 C++ 编译器MSVC(Microsoft Visual C++)GCC(GNU Compiler Collection)Clang 3. MSVC 编译器3.1 开发者命令提示符3.2 编译 C++ 代码 1.C++ 编译器 将C++源代码(扩展名为 .cpp )转换成计算机可以运行的可执行程序 编译器会检查代码的语法和语义,生成相应

linux编译器——gcc/g++

1.gcc linux上先要安装, sudo yum install gcc gcc --version 可以查看当前的版本 ,我们默认安装的是4.8.5的版本,比较低, gcc test.c -std=c99 可以使他支持更高版本的c标准 -o 可以殖指明生成文件的名字,可以自己命名,比如 gcc test.c -o my.exe -std=c99 或者 gcc -o my.exe

New的VC编译器实现

当我们调用 new 的时候,例如 int *p = new int; 时,编译器到底作了什么工作呢?跟进断点看一看。   (在 vc debug模式下 ) double *p1 = new double ; 00411A6E  push        8    00411A70  call        operator new (4111B8h) 00411A75  add

Linux系统应用(5)——编译器gcc

个人内容简介: 🍃个人主页:诉清风2023 🎈逆转时间的公式,就是珍惜现在ദ്ദി˶ー̀֊ー́ ) ✧ 目录 个人内容简介: 🎈逆转时间的公式,就是珍惜现在ദ്ദി˶ー̀֊ー́ ) ✧ 前言 1、预处理 2、编译 3、汇编 4、链接 5、gcc选项 6、函数库 6.1 静态库 6.2 动态库 结语 前言 重点 在软件开发的过程中,从源代码到可执

Linux编译器--gcc/g++使用

目录 一、预编译指令 1.1预处理功能 1.2指令 1.3问题扩展 二、编译(生成汇编)  三、汇编(生成二进制机器语言) 四、链接(生成可执行文件或库文件) 4.1库文件 4.2目标文件和库的链接 4.3动态库和静态库的优缺点 五、debug和release 一、预编译指令 1.1预处理功能 去掉注释头文件的展开条件编译宏替换 1.2指令 预处理指令是

CodeWarrior编译器中编译目标的设置

在CodeWarrior编译器中,生成的map文件中TARGET SECTION(编译目标)中有一项时Memory Model选项,这个的改变影响生成的s19文件,最明显的地方在于生成的s19文件中位于0xFFFE开头的地址中的数据会被改变。 对于地址模型的介绍,摘抄自https://blog.csdn.net/lin_strong/article/details/78127072 编译器