游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5391|回复: 0

Intel架构师沈熙-Javascript引擎原理及应用的分析

[复制链接]

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20468
发表于 2013-4-14 23:02:17 | 显示全部楼层 |阅读模式
  编辑注:CocoaChina2013春季开发者大会,于4月13日顺利举办,这里GameRes游资网作为合作媒体,为大家发送会议上的经验访谈。

  在技术研讨专场,我们有幸请到了来自Intel的架构师沈熙,沈熙是英特尔的专家,对JS引擎有很多年的研究。以下是演讲实录:

沈熙:非常荣幸有机会触控邀请我来做这样一个讲座,我先做一个简要的介绍,今天的内容可能会有点枯燥,大家在座的都是做游戏开发的,就我们国内来讲,绝大多数的开发者通常不会接触到非常底层的技术,可能有一些做Linux、Driver的,但是像语言和编译器很少接触到了,内容稍微枯燥一点,我也想办法尽量讲得浅显易懂一点。我今天的内容不会特别深,基本上是科普性的。


我是2003年加入英特尔,一直做编译器开发,大概做了七八年,基本上常见的X86架构和ARM,还有英特尔一些内部嵌入式的编译器,还有Java的虚拟机都有做。最近这两年对外打交道的主要是我们在开发者关系部,实际上就是把我们英特尔平台技术介绍给广大的开发者,就是在座的各位。这个刚好是我之前的一个工作背景,现在由于Javascript,原来好像是玩具型的语言,现在变得越来越重要,一些关键的应用,包括游戏开发者都很火了,所以我的同事彭晓波会出来做这样一个讲座。这是我们公司的惯例,都会有一些法律的声明,我就不讲了。

这是我今天的提纲,我大概会讲这样一些情况,首先是背景,我们讲一下Java虚拟机主要的两种实现方式,其实就是讲一个解释器和即时编译,大家如果以前做的话都会知道,所以我叫史前时代,在我们这个特别年轻的行业,实际上好几年前就是史前时代了。即时编译就是我们现在用了Java虚拟机主流的,在开源社区,比如说V8,还有Firefox的话,从2008年作为分水岭,我们之前称为史前时代,就是简单作为一个解释器来做的。接下来我会介绍一下Javascript本身这个语言的特性,这个语言有哪些特点,如果我们讲的话一天都讲不完,Javascript包罗万象,这个主要是作为一个虚拟机实现的角度来讲有哪些特征是我们必须跟传统的语言、传统的编译性语言不同的地方。我们根据这个语言的特点来讲虚拟机的一些基本原理,这个也不会是说把Javascript虚拟机从头到尾都讲,主要是不同点,对于我们做虚拟机的人一些挑战,这里面有哪些优化我会提出来。

根据上面我们讲的虚拟机的原理和Javascript这个语言的特点,我们来总结一下经验之谈,从我们语言实现的角度来讲,跟大家提一些建议,怎么样写Javascript可能会高效一些,因为我们可能是经常写Javascript,你说我这样写没错,咱们跑得那么慢,稍微改一下又好了,这到底是怎么回事?所以我们今天会稍微提一下这边的应用,一些最佳实践跟大家共享一下。最后一点我们就讲一下应用优化,大概有两个例子。最后是Javascript运行性相关的开源项目,在开源社区我们有哪些虚拟机方法或者是Javascript运行方面加速的项目,给大家简单介绍一下。

Javascript的历史,当时其实这个语言大家在网上也都知道,当时最早的时候一个公司的人做的,其实就是一个页面展示,再加上一个超级文本的链接就没有了。后来我们需要有一些动画效果这些简单的东西,Javascript就用来增加这个动态性的东西,这个人现在做CTO,他在Javascript方面也有很多的开源项目。那个时候是用于非常简单的脚本解释器,那个脚本解释器简单一句话来说,其实就是一个循环,就是去扫描都有哪些操作和哪些计算,其实更像我们当时用到一个命令行的方式,非常循环,一步步扫描,这样做就行了,非常简单。所以那个时候也满足他的需求,也没有什么性能需要,因为毕竟那时候客户都很简单,几十行、几百行、上千行的也比较少见,直接嵌入到页面里面,不会太复杂。在2008年之前,解释器还是有一个发展,最初就是一个简单的大的循环,后来我们在解释器这个领域引入了一个中间码,就是我们看到的自解码编译器,实际上现在还有一些脚本语言还是使用这样的解释器。在Android的之前的Java虚拟机就是用的纯解释器型的。那个纯解释器到现在Android上的应用都能跑起来,他是怎么做的呢?也有一些优化的手段,就引入了一个所谓的自解码的概念。

大家对于自解码从Java的时候听到比较多,并不是从源代码直接去做。所以我们来看,一个当代解释器通常会分四步,我们现在有一个例子,有一个变量,3.14,R是直径,算一下面积,这是很简单的三个表达式。大家如果上过计算机课的话就有一个编译课,前面是词法、语法分析,来做你这个词法、语法是不是合法,会不会出错有这样的检查。之后有一个自解码的编译器,你可以理解为就是一个常规的静态编译器,就像我写一个代码编成一个二进制代码一样,实际上它的目标是一种自解码。中间第二个黑框大家可以看到,这就是自解码。这个自解码大家可以看到,它其实很像汇编语言,但是又不是。它是一种类机器源,同时又与具体的硬件无关的语言,它的好处就是非常底层。但是它在执行的时候就会靠一个自解码解释器。那把自解码放进来以后一条条的做解释,比你直接在Script上来做要高效,原来相当于Java C那个东西,就是所谓的自解码编译器。

第一个的意思就是说,把PI这个变量的地址放到寄存器0,这里面做了一个编号,不是像ARM中,或者是X86的一直到R15,X86的64位也有16个计算器。这个把地址放到1号当中,把0号和1号计算机相乘放入2号计算机,把2号和1号相乘放入2号寄存器,再把2号寄存器存到S地址去,这就是我们自解码,大家可以看到这个非常接近。所以我后面用解释器的时候就是一个非常简单的解释器来做,我这个解释器是怎么做的呢?这就是我用C语言写的一个解释器简单的事例,这个PC是虚拟的程序指正,如果指向第一个0的时候,就一条条进来执行。那么怎么来看呢?其实我这个写得比较简单,也是一个循环。它会看这个指令的操作码是什么,我在这里发现操作码是乘法,就从PC值上第一个站里面去把第一个数据取出来,把目的数取出来,把第一个操作数和第二个操作数都取出来,这两个有一个相乘。大家可以看到1234,后面的意思是把它存到目的数的空间里面去。后面那个MUR,这一套语句就会生成真正的按照目标方式去执行,也就是说这一段程序是放在目标机上去运行的,无论是ARM还是X86。然后PC再加4,假定我们的自解码的话每一个都是4字节的话,我们加4,移到下一位再去做别的操作。后来有一个这样的操作,直接就去行了。加上4以后,就抄到下一条指令的解释代码去,这就是解释器一个简单的例子。这是2008年之前大家主流的几个浏览器,他们通常都是用这种方式来实现的。

到了2008年的时候,Google Chrome诞生了,它出来的时候效率一下子比那些传统的解释型的达到40到50倍的提升,大家吓坏了,怎么这么快?它到底有什么神奇之处?实际上也没有什么神奇之处,就是把即时编译的技术第一次引入。所以那个时候Javascript的虚拟机性能一下子就抬上了一个新的台阶。随后各家都开始注意,原来你在用这个,大家都用。所以用不了多久,他们后来做了另外一个,就把这个技术也引进去了。引进去以后,整个行业我们就会发现,Javascript的性能都提升起来了,除了IE保持了相当长的时间落后以后,它现在也追上来了,而且从我们测试的效果下来,IE10的性能相当好。所以到现在为止,大家每次发布新的浏览器的话都会强调自己的这个性能,所以这个军备竞赛从那个时候开始,到现在一直没有停止。这是我找了两个评测网站,我没有说是从哪里来的。大家可以去看一下这是三种开源Java虚拟机的性能,它是按时间来分布的。所以你说基本上看之前还有大的差距,那个趋势就是说大家都差不多接近了。也就是说,差的那一点对于实际应用的性能,因为我们用Javascript目前为止我们还没有人拿它去做高性能计算,所以这种差距,如果不是高性能计算,其他计算来说基本上忽略不计了,大家的性能都是一致了。

我们看到这样的趋势,感谢Google提出来,让大家都去重视这个事。就是因为这个性能急剧提升,大家猛然发现一件事,以前觉得Javascript做不了的事现在都能做了,因为性能差不多了。我们看到有一些项目,在Javascript这个项目当中甚至可以做到跟Java接近,甚至他写一个C++的版本,再写一个Javascript的版本的话,它的Javascript版本只比他快一倍,比如他10秒完成,他20秒完成,他们有的人说迟早有一天会达到只比他慢20%或者是30%的水平。这是很可怕的,因为Javascript的开发效率不是C和C++能比的。如果Javascript哪一天达到1.2倍和1.3倍原生应用性能的话,就可以应付任何事了。刚才Ricardo Quesada给大家看了iOS和Android的模拟器,大家知道,他们底层用的都是一个QEM的开放源的项目,这是一个法国人,他专门做仿真器、模拟器的,这个作者也是一个大牛人。他用Javascript写了一个X86架构的PC模拟器,竟然把一个Linux在一个浏览器里面下来了,一片哗然,连Javascript的创始人他都觉得很惊奇。大家可以到网上去搜Javascript PC,一旦运行起来非常快,你感觉不到这是一个浏览器。Javascript不仅仅是作为一个页面的动画,它是做很几层的事,一些系统性语言它也能做。

我们现在看一下Javascript虚拟机的一些主要实现特征。也就是说从实现者的角度来讲,Javascript有哪些特征。我们来看一下,在讨论Javascript虚拟机实现之前,先从实现者角度来讨论一下Javascript有什么特点。讨论起来没完没了,因为它太灵活了,我们只能从实践者的角度来看一下。它就有一个特性让我们觉得做语言的人特别头疼,就是动态性。我举了几个例子,就是变量无类型,你给我一个变量,一个X,一个Y,一个A,一个B,是什么类型不知道,在传统的语言当中,C++或者是Java,所有的变量,任何一个对象都是有定义的,这些都是明确的,在编译时间都能明确下来。但是Javascript语言变量是没有问题的,只有你在运行的时候才知道到底是什么类型。这个变量无类型大家可以想像一下,如果我一个解释器或者是一个执行引擎去执行到一个变量的声明的时候,对这个变量比如说声明一个A和B,我把A和B加起来该生成一切什么呢?A和B到底是生成什么样的呢?我根本不知道。所以我的执行引擎势必会充满了很多这样的Code,如果AA是浮点数,B是浮点数我该怎么做,A是一个整点,B是浮点我该怎么做,A和B都是整点怎么做?一定会出现这样大量的短小的分支判断,而这种其实对于当代的计算机,特别是深流水线损害是特别大的,特别是在一个多层循环体是非常差的。但是几乎所有的变量对它的引用都存在这样的问题,当然在标准的定义上有一个灵活处,就是Javascript的标准定义就是说,任何变形都缺省是一种浮点数来操作,如果是一个字符串的话,就做成一个字符串相拼。但是大家也知道,浮点数运算比整点数运算肯定要慢,它的性能是差的。所以所有的执行引擎都试图要把数值性的预算都尽量的转成定点性的运算。我后面会讲,加上虚拟机的话一般怎么处理这件事。对象属性可以在运行时改变或者是增减。我写一个根本不知道是什么,你是访问一个属性,还是访问一个方法,不清楚,只有在运行的时候才知道。在运行之前,我要生成一个Code该怎么生成?这是有很大的挑战的事情。函数式对象可以被人遗的操作和改变,它的程序的Code可以改变,理论上来讲,我用Javascript可以写一个Javascript的解释器出来,是一个自编程的语言,非常灵活,对于我们做虚拟机和编译器的人是很头疼的,在底下会讨论到底是怎么来解决这个问题的。这种动态性,就是我们在过去几十年业界所积累的编译和虚拟机优化方面的东西,都是基于一种静态类型的。这种技术积累对于这种全新的动态语言真的很难得到应用,所以这个确实也是一个很大的挑战。

根据前面我讲的那些特性,我们就要讲一下Javascript的虚拟机需要解决几个问题,从动态上来讲有几个问题需要解决。动态特性的确定,这个变量到底是整点、浮点还是字符串,越解决得早越好。大家可能学Javascript语言的话有一个最头疼的东西就是变来变去,到底这个方法是哪里定义的,从哪里找,可能你写程序的不关心,但是我们做执行引擎就必须搞清楚,你到底现在A是在哪里定义的,我们必须要清楚这一点。所以这个简单的定义就是说,这个程序当前能反问所有的程序和局部变量的集合,要做一个变量的搜索,找到你的方法。动态资源的管理,这个就是我们很熟知的,像垃圾回收器,当然这个算法其实跟传统的静态语言是比较类似的。还有生成高效的可执行机器代码,这个就是与传统的静态编辑优化比较类似,传统的常规静态编辑优化,比如说循环优化,一些循环不变量外剔除去,还有一些代码,其实从程序的逻辑上永远都不会被支持,这一块我们会删掉。当然你做寄存器分配,还有一些特殊机器指令的生成,这些都要用到。除了我前面标红色的动态特性,后面执行上管理、动态资源管理,还有执行代码这些传统的静态编译器,以及所谓的静态语言、类型语言这种其实是类似的,所以我不会在这个上面花时间,主要我们会讲一下动态特性的确定方面,就是一个变量怎么样来确定类型,怎么样去寻找那个方法,我会大概提一下。

这张图就是我们自从2008年有了这种架构的虚拟机的话它的基本架构,还是JS的源码进来,Parser跟前面一样,跟解释器方式是一样的,生成自解码。这个时候大家可以看到,往下面的时候有一个解释器,解释器还是跟前面的那个解释方式是一样的,除了V8的话,都是用这种方式做,也就是说并不先基于用这套东西,先解释执行一遍看,所以要去解释执行一下。然后这个时候这个Profiler会得到运行的信息。比如说我有一个变量,我发现它初始化永远只是8,我就照着这个变量定式一个整点的定点数,我对这个表达的话,我就尽量往这个方式去执行。还有包括其他的信息,比如说热点信息,他会知道哪一块指令代码,哪个分支运行时间最多,这个变量在这个过程当中到底变没有变,我是不是能够常量化,就是用一个常数来代替,这就是所谓的Profiler信息,这些交给了这个编译器,他就是利用这些信息,把上面的自解码翻译成Native Code,就直接转化成一个机器指令。这个编译器的运行完全跟解释器一般来说在设计角度来讲是一个并发的状态,所以它跟解释器之间是一个生产者和消费者关系,解释器发现某一个程序片段,或者某一个程序函数变得特别热,执行次数特别多的时候,他会放到一个编译队列去通知这个进程,说你去把他给我编译成Native Code。解释器到下一段的话,先去看你有没有生成这个机器指令。如果是生成了我就靠机器指令去执行,就不解释你了。V8做的是比较野蛮,什么中间档都不生成,直接把Javascript生成汇编,生成X86指令,跑了就完了。它里面有另外一个编译器,他会把这个生成的X86拿来看一看,是不是有些地方可以优化,再改一改再填回去,所以V8做得是非常简单粗暴。但是就是这种简单粗暴的方法特别有效,目前为止性能还是特别好,不能说是最好,还是非常好的。

回到前面的主题,就是动态特性的确定。动态特性的确定有两点:一是动态类型的确定,就是如何决定这个变量类型,从而生成对应机器码。一般的像Javascript用的数据流分析,简单来说就是我把你的程序扫描一下,看看你这些变量都有哪些值,能做哪些运算,这些初始之后能不能保持类型的一致性,如果能保持类型的一致性,我发现如果都是整形,这个变量就是整形,以后它参与运算我尽可能往整形去变。还有一种就是值域的分析,比如说我今天有一个判断,A大于B或者是怎么样,如果我发现A和B两个趋势一个是常数,一个是变数,比如说B我发现它永远是8,A我发现它永远都会大于8,这个判断我就消除掉可以不做了,这也是一个优化,也是可以用到的,他也会通过这个来确定一些类型信息。还有用得最多的,就是我来看一下你在整个执行中,比如说对于一个循环一般是100遍,我先执行100遍看看,这个是不是最Hot的地方,如果是最Hot的地方,我会把自解码抽出来,丢给进程让它去做,这是动态类型的确定。

动态属性和函数寻址,我要决定谁在哪里改变了这个属性。这个改变最多的方式,从概念上来讲就叫所谓的函数的查找表,我就先去找X Object,找到它以后我要看A,因为Javascript可以任意的添加,通常是没有办法确定的。通常最笨的办法就是作为一字符串的方法,这是一种最常见的方法。还有V8提出来的,每次对一个对象属性增加的时候,我回帮你生成一个所谓的隐藏类,其实就是来描述你当前的这个布局,就是这么简单,这样的话会减少对查找的搜索。但是它有一个代价就是会增加内容存,大家看的话,E8的内存用量是非常厉害的。多态内联缓冲,这个我后面会详细讲,就是怎么去动态寻址。

这是一个动态类型的确立和优化。我们先看一下动态类型,这里有一个功能是我们粗略算一下面积,一般我们是3.14浮点数,简单一下算,我不想用精算的算法,我用3来算一下面积,R就是一个属性,我要表示的半径,来看一下平方。后面有一个循环,让它的半径永远为8,这个Code很傻。但是我为了说明什么问题呢?我们来看一下到底是怎么做的。实际上对于我的虚拟机来讲,它真正要做的话就是我写在右边这段尾码,它会判断,FC.R是一个浮点的话,做什么计算呢?一个浮点的乘CDR再成CDR,如果CDR是一个整数的话,我就要把它变成一个整回的。如果你们有机会研究的话,它里面会产生大量的Code,所以你说Javascript有时候慢就是慢在这儿,当然这里面仍然是有优化的,这是理论上讲,如果分析不出来的话只能这么做。但是我们会分析这个循环,比如说10万次运行的话,前100次运行的时候,他会分析你这个R永远都是8。那么怎么办呢?我干脆就把整形这个运算,我也不要让你去函数都要用,直接把这个8带进去,乘进去,直接放那个过去。我觉得这样的话,我就没有了这个挑战了。但是仍然会出错,为什么会出错呢?因为比如说这个Code,我从一个静态分析角度来讲都能分析这个。有可能前1千次是8,后面会说R如果是大于0,小于1000的话他会用整点版本做,如果大的话会用一个浮点的版本做,再往后会用整点和浮点同时的去判断,这个都是在程序的执行上的。里面有一些技巧,就是在堆栈上先把这一块Code改掉。那个太细节了,我们就不去抠了。可以直接用整形代码,因为我分析它是永远都不会变的。

动态属性和方法,我这里这种Code就特别傻,我要算一下这个面积。大家知道,三角形、正方形、圆形面积算法都不一样。我的解释器或者是我的执行引擎,我看到Code大家想想看我该去调哪一个,我压根不知道。所以我怎么办呢?就是说我该怎么算?而且因为你这个Layout,假如说对于调用在后面,还不在前面,我先看到这个再从后面执行,我怎么去生成这个机器代码?怎么让它去执行?所以说通常用的就是我们底下这个表,就会生成一段之后判断,怎么判断呢?因为等到你运行的时候肯定就知道是什么了,做一个字符串比较,然后找到中间这个表,我去查。假如说我看到是一个正方形的话,我就找到正方形这个方法。这是我简化了的,实际上就是说,这三块最后会生成Code,插到这个语句前,我会取代码。你这一行Code对应成我的虚拟机的话会是一堆,这样附加的指令大概能增加几百,甚至是上千条,大家可想而知,这个Code你能写成千上万,几万这样的Code。但是对于我们来说,真正就是几百倍,所以这个性能为什么差就在这儿。全世界聪明的工程师们都在想办法,这个技术在六七十年代的时候有一些方法。这种就是所谓的多肽,就是你这个可能是各种类型,我怎么办呢?我在这条语句的时候实际上会这么做,因为我通过Profiles的信息,我发现你这个Area80%的情况下都是一个正方形,怎么办呢?如果你是正方形的话,还有10%的情况是圆形,还有10%的情况下是三角形。我就擦这一段的Code,如果你是正方形我就执行正方形的,如果是圆形我就执行圆形,如果是三角形我就执行三角形。Profiles的情况就是试运行一下,我一来就直接去执行正方形,虽然Code变多了,但是执行效率非常高,如果80%都是正方形的话,80%的可能性,我就直接执行了这个正方形的球面积。我再拉过去,看到这个正方形的时候,我再加一个判断。如果你不是正方形的时候,去做一个判断,万一没有结合就跳过去,但是好在这条Code不经常执行的,我们可以把它放到一个比较冷的代码当中,所以它的效率是很高,基本上我们的这个硬件里面的机制就可以非常顺利的把这个充满做下去,就是这样的速度会很快,这个效果做出来是非常好的,所以大家来看一下虚拟机是这么来做的。

前面我讲了动态变量,动态方法属性的确定,大概是这个一个概念,有非常多的细节。我们就来提一下,下面看一下我们该如何写出一些高效的JS代码,根据刚才那些特色,有一些建议。一个最大的原则就是说,尽量减少动态特性的使用,大家一听都觉得矛盾,就是因为动态特性,所以开发效率才高,尽量少使用,所以这就是一个矛盾,需要大家自己去平衡。你是要追求一个性能还是追求一个开发的效率,如果你需要一些性能的话就要特别注意,所以你尽量少使用,就是你的变量尽量少使用不同类型,刚才Ricardo Quesada提到要用Object的池,我听了以后有点摇头,我觉得这对于我们做虚拟机的人来说太难了,因为你如果用一个对象池的话,你这个对象会经常指向不同的内容,它的类型有可能是时刻在变化的,这个一来很难,二来对于我们做类型分析是一塌糊涂。当然里面也有一些类型变换,可以通过你的生命周期的分析,最后用不同的变量来表示也可以。所谓的动态平衡,就是对于一个简单变量而言,尽量保持其类型在生命周期内恒定,我生成的代码有一些分析技术就可以生成恒定的,而不是充满了那种跳过来的。减少对Closure的使用,这个都会占用时间。还有减少对With语句的使用,With语句就是为了让那个字句变短一些,这个也会做额外的搜索。减少Scope Chain的使用。密集型的业务尽量使用数组,就是你说这个数组的类型,就跟C++的传统是非常相近的。而且我觉得虽然Javascript这个科技的进步,如果大家用类型数字的话,我看到他们可以把程序做一个计算性的应用,甚至说我的渲染引擎本身操作都可以用这个来做,它的性能不比Native差,而且甚至有的可以加速。这方面在三星和诺基亚在做一些Web CL的应用也会用到。减少循环体内函数,最好能将函数Inline入循环体,会减少一些开销。

第一个案例分析,所谓局部面上的全局变量,第一个我把N从0到10万做一个累加。第二个函数很简单,还是有一个不变量,但是我会在这个内部定义一个Local变量,让L做累加,这个程序大家觉得没有任何问题。作为我们传统的来讲的话,你即使写第一种Code没问题,他肯定会把你优化成第二种,如果它能够分析出来这个访问是没有副作用的话,所谓的副作用就是说没有别人去改变他。我们可以看一下,左边这个Code我们可以看出来,我在这里面有两个红色代码,一定要把这个Global变量漏到这个变量里面,再回去。因为它分析不清楚你的全局的情况,他分析不清楚是不是有副作用,所以在Loop每次都要做,大家知道10万行的循环。右边很简单,你写到一个Loop变量的时候,他在外面就做这个变量,所以Loop里面不会有,你10万次的Loop循环的话,你就要比人家多20万的操作,这样下来性能差50倍。

我们再看一下With语句使用,这种代码我们常常写,也很简化。右边的话做了什么?实际上后面红色的就是在虚拟机上做的事情,实际上要去判断,也就是说,他要对这个进行搜索,没有的时候他才去做。所以这种Code的话会做额外的判断,而且你这个内容又特别大的时候,也能够差几十倍,看起来显得很简单,内部发生了很多事。我们再来看一下Closure闭包,实际上我生成的Code,如果要生成这个里面的Closure这个变量的时候,大家看它一定每次都把A和B放进来,每次都要生成,然后我再做一些运算。所以说前面那两个就是不是仅仅写了一条,如果先找外层,一直到找到为止,否则报错了。这种Code大家看起来显得很简单,这样定义,但是时间在桌子底下的事特别多,很折腾,所以大家要大概知道,这个Closure会是一个变量。

ASM JS这个实际上就是一个Javascript的一个标准子集。它的用处是想把C和C++这样的代码编译成这样一个东西,在现有的方式下运行。它的性能大概是原生程序的一倍,相当不错。我用CA写一个算法,我现在把C直接生成X86在跑,性能只差一倍,相当可观,大家有兴趣可以看这个官方网站。还有这个项目是借助于开源的我们的明星项目LLVM,现在主要是由苹果来维护的,当C和C++静态编译程成Javascript,大家可以想一下,如果用这种C++写的话,完完全全不需要任何插件,大家觉得这个可能有点多余,C++程序怎么跑?但是你要知道,我们有很多传统的一些C++的Code,这是一个很了不起的东西。还有Paralle Javascript,能够更好的利用,它做了一些改进,有一些API可以更好的利用我们的并行指令和多核架构,他现在已经提交了草案了。

我就介绍到这里,谢谢大家!

问:我想问一下LLVM那个东西可以编译脚本语言,是不是它编译出来的那个东西跟C++什么的编译出来的效率上都一样呢?
沈熙:大家可能对LLVM感兴趣,它实际上是把任何一种高级语言,不管是Javascript语言还是什么语言,它会生成一种自己定义的自解码非常高效,这种是高度可移植的,可以用一个汇编器汇编成任何你想要的代码,而且可以基于这个做很多语言级的分析。但是从性能上来讲是一模一样的,只是说它这个架构特别好。现在在GPU里面做Shader这个引擎的话,几乎都采用的是LLVM架构。

谢谢大家,比较仓促,希望大家有所了解。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-26 23:26

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表