[译]Javascript:自托管的Parallel JS

原文:http://smallcultfollowing.com/babysteps/blog/2012/12/05/self-hosted-parallel-js/


译者注:此文翻译不通顺,你只需要读懂大概.

我已经有段时间没写博客了,原因是我最近正忙着搞Parallel JS,已经花了不少时间了.不过,我们的目标是:在接下来的几周内发布一个最初版本!

一个令人兴奋的消息是我们已经开始了自托管(self-hosting)的实现.自托管是一个非常酷的,由Till Schneidereit发起的,SpiderMonkey引擎新的发展方向.其核心思想就是"使用JavaScript来实现Javascript引擎自身的大部分功能",类似于Squeak, Jikes RVM, Maxine, PyPy以及许多其他的项目.举个例子,想一下标准的Javascript函数Array.map.在SpiderMonkey中,该函数使用了大概80行C++代码.这些代码必须要处理各种烦人的条件验证,比如要确保所要处理的对象是已根化的(rooted),检查中断(interrupts)等,还要使用一个优化过的调用序列(call sequence)来让JavaScript代码运行的更快.如果这个函数是使用Javascript写的,那么所有的这些问题都会自动转交给Javascript引擎来处理,就像处理其他非原生函数一样.

除了复杂度,使用C++实现的Array.map的另外一个缺点是:慢.你也许会大吃一惊:难道C++不比JavaScript快吗?答案是"是的,是快",C++写的程序可以比JavaScript快,不过必须是在操作C++中的数据结构的前提下.等价的数据结构在JavaScript中会表现的完全不一样.比如,一个C++中的数组仅仅是一个存储器单元(memory locations)的连续序列(continuous series),所以一个数组存储操作比如a[i] = v会被编译成极少量汇编指令(assembly instructions).而在Javascript中,数组灵活了许多:它们可以是稀疏的(sparse),可以动态的增长和缩减(grown and shrunk).所有这些都意味着,一个相同的数组,在JavaScript中会比在C++中有更多更复杂的操作.目前,SpiderMonkey中的实现是调用了JavaScript VM函数SetArrayElement(),该函数非常通用,可以处理所有可能遇到的情况.

使用一个辅助函数是不幸的.因为,在通常情况下,一个JavaScript数组在引擎内部就是使用一个简单的C++数组来表示的,这就意味着,存储操作a[i] = v可以被编译成为C++中等同的操作.实际上,对于一个写在JavaScript中的循环,JIT引擎也会用类似的方法把循环编译到C++中,在执行中,如果有必要的话,会调用一个类似SetArrayElement()通用操作.

还有一些其他原因让C++代码比JavaScript代码慢.比如GC接口就比较尴尬,由于编译器不能生成一个堆栈地图来告诉我们指针在哪里,C++和JavaScript代码之间的转换就需要一些适应,因为IonMonkey编译器专门针对JavaScript的需求使用了一个调用惯例.等等.

内部函数

当然,用Javascript来替换C++并不是一帆风顺的,同样会伴随一些负面的影响.比如,C++代码可以做一些普通Javascript代码不能做的事情(比如访问本地文件).还有在自托管的实现中,JavaScript函数必须处理一些平时不需要关心的内部细节.为了解决这些问题,自托管引入了内部函数(intrinsic function)的概念.一个内部函数就是一个特殊的JavaScript函数,用C++实现,而且仅允许自托管代码调用.内部函数的作用就是暴露额外的功能(进行一些引擎内部的操作)给自托管代码,其它的非自托管代码不能调用这些内部函数.

为了和普通函数区分开来,目前Parallel JS中的内部函数以%符号开头(比如, %Foo()),不过未来的计划是使用普通的Javascript标识符来替换这些名字.

在Parallel JS中,我们使用内部函数暴露了一些底层的并行操作,这些操作可以用来实现其他更高级的并行操作(map(), filter(), reduce(), scan(), scatter()).和高级操作不同的是,内部的并行操作并不安全,它可能造成数据争用(data races)的情况.还有,如果调用这个内部操作的高级函数出于某种原因不能被编译成并行操作的话,这个内部操作也会失败.

posted @ 2012-12-06 15:14  紫云飞  阅读(1412)  评论(0编辑  收藏  举报