之前了解了一下方舟编译器,但是很粗,今天在知乎上看了各种大神关于方舟编译器的说法,其实一直以来就有几个问题,我看了知乎上的说法,突然觉得这些人都是很懂计算机的,那下面这个疑问点应该也很好解释吧。
要说问题首先要说下这个编译器的概念,毕竟计算机科学领域的网友看到这篇文章的概率还是不大,大多数还是普通网友。
简单来说,编译器其实是把人能看懂的代码转换成机器能看懂代码(程序)的程序,理解到这里就够了,不要理解什么高级语言低级语言这些,那么就有点太多了,当然复杂点这里面就包括很多技术了,什么预处理器、编译器、链接器等等还有什么语义分析、代码优化等各种技术。这里就不说了。编译器的基本告诉我们的东西有三点:
- 编译器只是一个在开发阶段使用的工具,而在代码执行阶段需要与编译器配套的另外一套东西来运行(运行时环境,也就是运行期间需要的一个东西)。大名鼎鼎的WinTel联盟就是个例子,windows的CPU完全兼容Intel的CPU,CPU也为Windows的上层程序提供专门优化。再从计算机角度来说,C/C++有自己的运行库,Java有JVM,.Net有自己的运行时,Javascript也有自己的虚拟机。玩游戏的都遇到过什么VC++ Runtime需要装各种dll的情况。Runtime的中文翻译就是运行时,也就是我们在玩游戏的时候,通常这款游戏是基于某个VC++的版本开发的,而运行时就需要这个VC++的运行时环境。
- 问题1其实也引申出来了一个问题就是开发工具必须要有对应的运行时环境与其搭配才可以。
- 机器能看懂的代码,机器能看懂的代码一定是01010101吗?不一定的,尽管最后交给CPU、GPU的一定是01001,但存储的不一定是,在计算机里程序必须通过操作系统来执行,也就是最终的执行须由操作系统负责执行。
那么好基于上述三个点,我们一个个来看下方舟编译器怎么做的?
- 第一个现在方舟编译器是如何做到跨CPU生成机器码的?现在的手机CPU的指令集基本上差不多,都是ARM的架构,但是也有一定差异,现在市面上有高通,联发科,三星,麒麟等各类CPU,如果说只要一次编译就能完成横跨各CPU的差异,这个可能吗?如果可能的话,我是不是可以这么理解,苹果的A系列处理器也是ARM的架构,那么方舟编译器只要能按照苹果的要求组织文件结构,编译出来的程序也可以在苹果上运行?好像是不可以的吧?有研究的童鞋可以进来解释下。
- 第二个,方舟编译器的运行时环境是什么?
这是方舟给出来的运行结构,从图上看不出来什么运行时兼容层,如果没有运行时兼容层,直接编译成二进制码,为啥还需要手机做兼容呢?按理说直接是二级制编码了可以直接执行啊。这也间接印证了,所谓方舟编译器并没有做到跨平台的生成机器码,而是使用兼容层方案,那么这和现有安卓的区别在哪?又或者上面的PPT是”不小心“制作错了?当然了我们不排除华为有很牛逼的技术能力,连这个运行时环境都不需要。直接编译个Linux程序,可是学过计算机的都知道搞嵌入式编程只能一机(准确讲叫一型号或结构)一程序,否则又哪来的Android碎片化呢?说到这顺便说一句,华为的手机通常的更新期都不会超过18个月,如果说华为都能从程序层面撇开运行时环境,直接生成机器码,那么是不是每个手机都可以及时更新,一直维护了?
3. 我们知道安卓的底层是Linux,那么Linux是否允许程序绕过自己直接执行机器码呢?这是一个Linux的系统结构图。
很明显应用程序是无法绕过系统调用,来直接进入内核调用,因此无法执行机器码,必须走共用函数库。或系统调用。因此我们在方舟编译器很牛的前提下只能假设这个编译器是直接调用共用函数库和系统程序。这个有没有听着很熟悉呢?对了就是Flutter,Google新推出的一个跨平台开发跨级啊。当然除了Flutter还有一个跨平台框架叫Xamarin。不过这个呢不是调用系统底层,所以不讨论。我们看看Flutter的架构,很幸运我在网上找到了一个Flutter的结构。
最上层是Dart语言的适配或者说接口层,通过Framework调用C/C++的Engine,Framework的上层就是我们的应用程序。Flutter制作的APP在编译以后呢会把Framework直接包裹到APP里。方舟编译器就很牛逼了,只需要用他们的编译器就没有Framework可以直接调用C/C++库了,心里这一项还是很为华为感到......(自行脑补吧)
好吧我们假设不需要Framework是可行的,那么新的问题来的,你用java/kotlin写的安卓APP,调用的很多底层的东西都是所谓的ART虚拟机才支持的,那么华为是如何让这些底层的接口直接映射到底层的C/C++库的?
4. 还有一个很现实的问题,华为有这么一段话:
华为从2009创建编译组开始,到2013年华为方舟编译器架构构想(方舟前身)正式提出,再到2019年方舟编译器的正式应用,这其间花了整整十年,这十年间的无数失败、无数次的重来,其间的艰辛,编译组的科研人员是最有话语权的。
根据Android的时间线,
2009年Android刚发布2.0版本,
2013年Android4.4发布。华为开始提供方舟的的概念。
2014年Google推出ART。
我们把时间再退后2年到2016年,基本上Davlik虚拟机就没有了。那么在这时我有个疑问了,如果说APP可以在编译期直接编译成机器码执行,那么ART为什么还是在执行安装时编译,ART里有一个功能点很重要,叫AOT(预先编译),根据官方说法ART会在APP安装时编译成对应的机器语言,那就是很神奇的一点,既然Google的ART也是编译成机器语言,方舟也是编译成机器语言,为什么ART不直接编译成绕过VM的底层语言?Google都有心情更换Davlik虚拟机了,做个这么个事有什么难的吗?而且相比华为,Google应该更有动力去提高Android性能吧。2016年不管从商业动力,技术动力,Google显然比华为更应该去做,Google可能是真的傻X吧,连这么简单的事都想不到。
如果说AOT是高性能Google为什么后来还加入了JIT?这都不合逻辑啊。
好吧,最后我们假设华为需要一套运行时环境(反正给的图没看出来),那么也就是说方舟的运行时环境只是对ART进行了优化,但是这个能不能被称之为编译器来混淆视听就不好说了。
或许等到方舟编译器开源的那天才能真的知道?