现在连移动设备都具备了并行处理能力,但 JavaScript 仍然是串行的。Intel 实验室正在着力创建 JavaScript 的一项扩展,该扩展会利用多核系统优势,并已发布了Firefox 插件。InfoQ 对来自Intel 实验室的Stephan Herhut 进行了关于这项工作的独家采访。
这种开发代码为River Trail 的JavasScript 扩展是Intel 实验室的一个项目,该项目致力于将Intel 多核CPU 的处理能力以及向量扩展(vector extension)应用于web 应用程序中。River Trail 正努力使计算密集型(compute intensive)应用程序——如图像编辑软件——能在浏览器中运行。
River Trail 使用确定性数据并行结构对 JavaScript 进行扩展,该结构在运行时会被转换到底层硬件抽象层。通过调控多个 CPU 核心与向量指令, River Trail 将大大提高并行 JavaScript 的性能。。
值得注意的是,River Trail 在 JavaScript 中添加了 ParallelArray 数据类型,这是存储真实并行数组数据的只读数据结构。我们可以用 JavaScript 数组,类型化的数组,或用于产生并行数组数据的函数来创建并行数组。例如,“new ParallelArray([1,2,3])”将创建一个存储数值 1,2,3 的并行数组。该数组的内容能够被 combine , filter , map , reduce 等对数据进行并行处理的函数访问。分配给它们的 JavaScript 函数会编译成 OpenCL。这些函数能够使用 JavaScript 的一个子集。
InfoQ 对来自 Intel 实验室的 Stephan Herhut 进行了关于这项工作的独家采访。
InfoQ:请问开发 River Trail 项目的动因是什么?
Stephan:该项目开始的时候我还不在 Intel,所以我问了参与这项工作的 Rick Hudson,这个项目是如何开始的?他说:
“因为我们相信可以对多核程序和向量指令系统进行简化,从而提高编程人员——特别是使用 JavaScript 的 web 应用开发人员——的生产力。向 web 应用开发人员提供高性能和高生产力的结构是个棘手的问题,同时也是激励我们的原因之一。”
我在年初就参与了这个项目,真正使我感到兴奋的是 River Trail 非常符合 HTML5 技术。有很多问题限制了 web 应用能够具有内建应用所具有的功能,HTML5 解决了很多方面的问题。然而,谈到性能时,web 应用仍然有很大的差距。浏览器厂商在提高 JavaScript 引擎性能方面已经做了很多工作。当我在内建 JavaScript 中看到 broadway h.264 这样的解码器时非常惊讶。然而,JavaScript 基本上是串行的。WebWorker 允许后台长延时处理,但对于并行计算来说过重。River Trail 解决了数据并行处理的问题,我们在 GitHub 上的原型证明了这是一种可行的方法。
InfoQ:你认为与直接编写 OpenCL 代码相比,使用 JavaScript 作为输入语言的关键优势是什么?
Stephan:这个问题涉及两个方面:一是对 web 开发者来说有什么好处,二是对 JavaScript 引擎开发者以及对浏览器来说有什么好处?
对 web 开发者来说,我相信最大的好处就是易于使用:他们不需要学习一门新语言,能够继续使用他们熟悉的编程环境。RiverTrail 建立在已有的 JavaScript 概念之上,比如数组,map 和 reduce 函数,作为函数参数的闭包等等。在 River Trail 中并没有新的语言结构。所以,很多情况下开发者能直接在 Reiver Trail 上重用他们的代码。他们需要将 for 循环替换成 River Trail 的基本类型,比如 map,仅仅如此而已。实际的实现方式通常不需要变化,至少我们希望如此。我们目前的项目原型还不能做到这样,但我相信我们最终能实现。问题的另一个方面是对引擎开发者来说有什么好处?最大的好处就是安全性。浏览器是一个主要的攻击入口,而用户希望浏览器能提供安全的上网体验。OpenCL 是为客户端应用程序设计的,用户通常会从安全的地方得到安装程序。它基本上是 C 语言的翻版,具有 C 语言一样的功能和安全问题。因此,JavaScript 是被设计成在 web 上使用的语言,来自 web 的代码通常不可信。我们坚持这样的设计原理,即 River Trail 使用和序列化执行同样的安全机制,比如数组边界检查。
另外一个问题是普遍性。web 应用程序运行在许多不同的平台和设备上,从笔记本到手机都有。在这些平台上 JavaScript 普遍存在,但 OpenCL 也许不存在。River Trail 在浏览器 JavaScript 引擎上的内建实现可以将 RiverTrail 代码转换成向量化的机器码。即使完全序列化的执行也是有效的。API 都是经过精心设计的,很具有一般性,允许有许多不同的实现方式。
InfoQ:存在不能用 JavaScript 语法来表达的 OpenCL 代码吗?JavaScript 缺乏类型声明不会出现问题吗?
Stephan:我们从来没有把 RiverTrail 成 web 版的 OpenCL。只是我们恰巧在项目原型中使用了 OpenCL 作为后台技术。RiverTrail 使用了更高层次的抽象。因此,我们并不支持底层 OpenCL 特性,比如本地内存共享,同步屏障或工作组。这些特性是 OpenCL 才应该有的,但并不适合 River Trail 这样高层的 API。类型问题并没有我们所想的那样大。首先,WebGL 引进的类型化数组已经能让程序员操纵 JavaScript 中的数据存储方式。这已经一定程度上在我们的 River Trail 项目原型中采用了。其次,JIT 引擎在优化数据表示上越来越强大。JavaScript 类型推断的研究取得了不错的进展,目前能推断出哪些计算最好在哪些类型中执行。RiverTrail 顺其自然地受益于这些进展。
InfoQ:有可能在某些地方将 River Trail 和 WebCL 一同使用吗?如果这样的话,可以保留一个纯 JavaScript 的版本吗?比方说不需要内建 OpenCL 库的版本?另一个想法是整合 WebCL 和 WebGL。好像 River Trail 能够从 Canvas 中获取位图数据,但好像它是在 OpenCL 内存之间来回复制的。通过整合 WebGL 和 WebCL,有可能可以获取 WebGL 数据,用 WebCL 进行处理(使用 River Trail 产生的核心),然后再将数据转移到 WebGL,而不用将它复制回浏览器内存。
Stephan:我们决定实现自己的 Firefox 浏览器扩展完全是由于历史原因。当我们开始 Reiver Trail 工作的时候还不存在 WebCL,而当 WebCL 出现后我们已经实现了自己的接口。该接口相当于 WebCL 的简化版本。在 GitHub 上有一个 River Trail 的分支项目,该项目使用 WebCL 作为后台实现,而不使用我们的 Firefox 浏览器扩展。但我不确定该项目是否支持在 WebCL 和 WebGL 之间进行缓存共享。我现在关注的重点是从 web 开发者那里了解 River Trail 是否符合他们的需求,然后根据他们的反馈改进 API。我欢迎有人能开发一个基于 WebCL 的版本,并乐于提供帮助。我很有兴趣看看这种方式能有怎样的改进潜力。
InfoQ:你们目前支持什么样的 JavaScript 语言结构?你们计划提供更多的支持吗?
Stephan:我们在 GitHub 上的项目原型是对概念的验证,也是我们对语言特性的实验。目前,我们只支持基本数据数组。我们虽然也支持内嵌数组,但要求其具有最简单的形式,例如,我们将 canvas 中的图像数据构建成具有 4 个元素向量的矩阵。另一个限制是我们不支持对全局数值的引用和在内核中的函数调用。这些限制大多数是由于我们的原型不是在 JavaScirpt 引擎内实现的。相反,我们的编译器是用 JavaScript 语言编写的,并运行在 JavaScript 引擎之上。此方式能让我们迅速地构建原型特征,但限制了我们访问引擎的内部信息。SpiderMonkey 正在进行将更多内核信息暴露到脚本层的工作,一旦此工作完成,我们会看看是否能再消除掉一些限制。但最终来讲,River Trail 应该直接成为 JavaScript 引擎的一部分。
InfoQ:OpenCL 目标语言对于你们提供 JavaScript 特性支持有哪些限制呢?
Stephan:最大的限制就是堆管理。OpenCL 要求我们显式地将那些我们要从内核中访问的 JavaScript 堆映射到 OpenCL 堆。这就是我们目前只支持基本类型密集数组的原因之一。要完全支持内嵌数组和任意对象的数组,须要遍历和深入地复制底层数据结构。这在 CPU 上执行是不可行也没有必要的。
InfoQ:关于数值,你们将 JavaScript AST 中的所有数值都转换成双精度浮点型吗?还是你们会区分双精度浮点型和整型?(例如:‘x = 42’会被转换成整型吗?)
Stephan:JavaScript 语义要求所有计算都应在 64 位浮点上进行。但我们通常不需要这样高的精度,River Trail 允许 web 开发者指定在内核执行时使用 32 位浮点。除此之外,我们已经实现了一系列分析,用以推断在整型上计算是否安全。在循环边界判断上通常就是这样。对于你的例子,如果我们的编译器能证明对 x 的连续写操作能保持在 32 位整型值范围之内,‘x = 42’就会使 x 作为整型存储。如果我们不能验证这样做的稳定性,那么 x 就会作为单精度浮点型或双精度浮点型存储。
InfoQ:ParallelArray 目前是 River Trail 提供的主要抽象。你们有提供其它抽象的想法吗?或者说所有的任务都能被映射成 ParallelArray 吗?
Stephan:ParallelArray 抽象非常符合数据并行负载。并行编程的另一个有趣主题就是任务并行负载。分而治之的样式算法也在这个主题之内。webworker 也有同样的特性,但它们过于复杂,同时也不支持状态共享。我还不知道确切答案,但任务并行是个值得研究的领域。
InfoQ:在 web 开发者可以直接调控 GPU 和多个 CPU 核的情况下,你认为 web 应用在不久的将来会有什么样的进步?
Stephan:我自己不是 web 开发者,但我非常敬佩他们的创造力。当看到 Chrome 和 Mozilla 的 WebGL 示例出现的时候,我坐在我的笔记本前感到非常惊讶。所以很难预料将来会发展成什么样。在功能上,web 应用将会越来越像内建应用,但在其它方面又会有很大的不同。web 应用最大的优势就是它们的连接性。它们可以使用不同的数据源,将数据进行整理,实时地更新数据,用很炫的视觉效果展现数据。我希望 web 能变得更具有渗透性,而不仅仅是以页面为中心。我能肯定的是我将会为 web 开发者创造出来的东西感到震惊。
InfoQ:该项目接下来的计划是什么?
Stephan:我们目前正在努力提高原型的适用范围,同时正在探索如何尽可能地完全支持 JavaScript。其中一部分工作就是将 River Trail 直接引进 JavaScript 引擎。我们正在与 Mozilla 合作将 RiverTrail 整合进它们的下一代 JavaScript 引擎,同时我们也欢迎与其它浏览器引擎的合作。还有另外一项重要的工作就是处理用户反馈。最终,我们希望 RiverTrail 成为 JavaScript 的一部分,作为一项开放标准。我们想保证它确实能满足 web 开发者的需求以及他们关注的可用性。我们想依靠 web 社区来完成这些事情。请玩玩 RiverTrail,用它构建新玩意,并将意见反馈给我们。
查看英文原文: WebGL, WebCL, MultiCores: The State and Future of Parallel Javascript in the Browser with RiverTrail
评论