Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News WebGL, WebCL, MultiCores: The State and Future of Parallel Javascript in the Browser with RiverTrail

WebGL, WebCL, MultiCores: The State and Future of Parallel Javascript in the Browser with RiverTrail

This item in japanese

JavaScript has remained sequential although parallel processing capabilities are currently available even on mobile devices. Intel Labs has been working on an extension of JavaScript that takes advantage of multi-core systems and has released a Firefox plugin.

These parallel extensions for JavaScript, code named River Trail, is an Intel Labs project which tries to bring the processing power of Intel’s multi-core CPUs and their vector extensions to web applications. River Trail will try to make possible more compute intensive applications like photo editing, inside the browser.

River Trail extends JavaScript with deterministic data-parallel constructs that are translated at runtime into a low-level hardware abstraction layer. By leveraging multiple CPU cores and vector instructions, River Trail is claimed to achieve significant speedup over sequential JavaScript.

In particular, it adds the ParallelArray data type to JavaScript, a read only data structure holding the actual Parallel Array data. Parallel Arrays can be created from JavaScript arrays, typed arrays, or a function that is used to generate the ParallelArray’s values. For example “new ParallelArray([1,2,3])” would create a ParallelArray holding the values 1, 2, and 3.  The result is a ParallelArray whose contents are accessible by functions like combine, filter, map, reduce, etc. which work on the data in parallel; JavaScript functions provided to them are compiled to OpenCL. These functions can use a subset of JavaScript.

InfoQ had an exclusive interview with  Stephan Herhut from Intel Labs about this work.

InfoQ: What was the motivation for the River Trail project?

Stephan: I wasn’t at Intel when the project started. So I have asked Rick Hudson who has worked on it from the very beginning how it all started. Here is what he said:
“We were motivated by the belief that programming for multi-core, many-core, and machines with vector instructions could be simplified and made available to productivity programmers, in particular web application programmers working in JavaScript. Providing high performance, yet high productivity constructs  to web application programmers is a tough problem and that was one of the aspects that intrigued us.”
I have joined the project early this year and what really excites me about working on River Trail is its close fit within the context of HTML5. HTML5 addresses a lot of the issues that have limited what web apps could do compared to their native counterparts. However, there is still a big gap when it comes to performance. Browser vendors have done a fantastic job at speeding up their JavaScript engines. I was amazed to see things like the broadway h.264 decoder in native JavaScript. Yet, JavaScript still is mostly sequential. WebWorkers allow for long latency operations in the background but are too heavyweight for parallel computing. River Trail fills this void for data-parallel operations and our prototype on GitHub shows that it is a viable approach.

InfoQ: What do you see as the key advantage of using JavaScript as input language as compared to just writing OpenCL code?

Stephan: There are two perspectives to this question: What are the advantages for the web developer and what are the advantages for the developers of JavaScript engines and ultimately browsers.
For web developers, I believe the main advantage is ease of use: They do not have to learn a new language and can stay within their well-known programming environment. RiverTrail builds on existing JavaScript concepts like arrays, functions like map and reduce, closures passed as function arguments, etc. There really is no new language construct in RiverTrail. Also, in many cases web developers can directly reuse their code when moving to RiverTrail. They will have to replace for-loops by RiverTrail's primitives like map but that is pretty much it. The implementation of the actual workload usually does not change. At least that is the vision. Our current prototype with its limitations is not there, yet, but I am confident we will get there.

The other side to this question is what the advantages for engine developers are. The major advantage here is safety. The web browser is a major attack surface and users expect their browser to ensure a safe web experience. OpenCL was designed for client side applications, which typically are installed by a user from a trustworthy source. It's basically a dialect of C with all its power and all its dangers. JavaScript, however, was developed to be used on the web where generally code is not trustworthy. We keep that design philosophy. RIverTrail uses the same safety mechanisms that are used for sequential execution, like for example array bounds checking.
Another issue is availability. Web applications run on many different platforms and devices, from laptops to mobile phones. On all those platforms JavaScript already is available whereas OpenCL might not be. A native implementation of RiverTrail in a browser's JavaScript engine might directly translate RiverTrail code into vectorized machine code. Even a fully sequentially execution would be valid. The API design on purpose is general enough to allow for many different implementations.

InfoQ: Is there OpenCL code that can't be expressed in JavaScript syntax? Isn't the lack of type annotations in JavaScript an issue?

Stephan: RiverTrail was never designed to be an OpenCL for the web. We just happen to use OpenCL as a back-end technology in our prototype. RiverTrail uses a much higher level of abstraction. Consequently, we do not support lower level OpenCL features like local shared memory, synchronization barriers or workgroups. These are too OpenCL specific for a high-level API like RiverTrail. Types turned out to be less of an issue than we anticipated. Firstly, typed arrays that were introduced for WebGL already give the programmer a tool to influence the storage layout of data in JavaScript. We to some extent exploit that already in the RiverTrail prototype. Secondly, JIT engines are getting better in optimizing the representation of values. There is some great work on type inference for JavaScript that does a good job at inferring the type some computation would be best performed in. And RiverTrail automatically benefits from that progress.

InfoQ: Will it be possible to use River Trail with WebCL at some point? In that case, would a pure JavaScript version be possible? Ie. one that doesn't not need native OpenCL libraries? Another idea would be combining WebCL and WebGL. It seems that River Trail can take bitmap data from a Canvas but it seems to copy it to/from OpenCL memory. By combining WebGL and WebCL,  it might be possible to take WebGL data, process it with WebCL (with kernels generated using River Trail) and move it back to WebGL without copying back to browser memory.

Stephan: Our decision to implement our own Firefox extension has purely historical reasons. When we started the work on RiverTrail there simply was no WebCL and by the time it became available, we already had implemented our own interface. The interface is a simplified and reduced functionality version of WebCL. There already is a fork of RiverTrail on GitHub that uses WebCL as back-end implementation instead of our Firefox extension. I am not sure whether that supports buffer sharing between WebCL and WebGL. My focus currently is on learning from web developers how well RiverTrail fits their needs and evolving the API based on their feedback. I welcome anyone to build a WebCL based version and offer my support. It would be interesting to see what optimization potential that approach offers.

InfoQ: What JavaScript language constructs do you support currently? Do you plan on adding more?

Stephan: Our prototype on GitHub is a proof of concept and a place where we experiment with language features. Currently, we only support arrays of primitive data. We do support nested arrays but only if they have a regular shape. For example, we model the image data from a canvas as a matrix of 4 element vectors. Another restriction is that we do not support references to global values or function calls inside of kernels. Most of these restrictions stem from the fact that our prototype is not implemented inside of a JavaScript engine. Instead, our compiler is written in JavaScript and runs on top of the JavaScript engine. This approach allowed us to quickly prototype features but limits our access to internal information of the engine. There is work going on for SpiderMonkey to expose more internals to the script level and once that becomes available we will check whether we can lift some more limitations. Ultimately, however, RiverTrail should become part of the JavaScript engine directly.

InfoQ: How does the OpenCL language target limit the JavaScript features you support?

Stephan: The major limitation is heap management. OpenCL requires us to explicitly map those parts of the JavaScript heap that we want to access inside of a kernel to the OpenCL heap. This is one of the reasons why we only support dense arrays of primitive types at the moment. Full support for nested arrays and arrays of arbitrary objects would require traversing and potentially copying the underlying data structure. This is not feasible and would not be necessary for execution on the CPU.

InfoQ: Numbers: do you translate all numbers in the JavaScript AST as doubles or do you distinguish between doubles & integers?  (ie. will 'x = 42' be translated to an int?).

Stephan: JavaScript semantics require that all computations have to be performed in 64Bit floating point. Often that level of precision is not required and RiverTrail allows the web developer to specify that 32Bit floating point should be used during kernel execution instead. Beyond that we have implemented a range analysis that infers whether it is safe to compute on integers. This is commonly the case for loop bounds. In your example, 'x = 42' would lead to x being stored as int if our compiler can prove that consecutive writes to x will stay within the range of a 32 bit integer value. If we cannot show this statically, x will be stored as a float or double.

InfoQ: ParallelArray is the currently the main abstraction River Trail provides. Do you have ideas for other abstractions  or can all tasks be mapped to ParallelArray?

Stephan: The ParallelArray abstraction is a good fit for data-parallel workloads. Another interesting domain in parallel programming are task-parallel workloads. Divide and conquer style algorithms belong to that domain. Web workers somewhat go into that direction but they are too heavy weight and do not allow for shared state. I do not have an answer yet but task parallelism is an area worth looking into.

InfoQ With web developers being able to directly leverage GPUs and multiple CPU cores, how do you see web apps evolving in the near future?

Stephan: I am not a web developer myself and I have huge respect for their creativity. When the Chrome and Mozilla demos for WebGL came out I was sitting in front of my laptop in awe. So it is really hard to predict where things are going. Web apps will become more like native apps in terms of their capabilities but they will be totally different otherwise. A huge advantage web apps have is their connectivity. They can tap into different data sources, mash things up, add live information and present it all using stunning visuals. I expect the web to become more immersive and less of a page centered web. The only thing I know for sure is that I will be surprised and amazed by what developers came up with.

InfoQ: What's the future roadmap for the project?

Stephan: We are working on lifting limitations of the prototype and exploring how far we can push towards support of full JavaScript. Part of that is putting RiverTrail directly into JavaScript engines. We are collaborating with Mozilla to integrate RiverTrail natively into their next generation JavaScript engine and we welcome any help on reaching further browser engines. Another really important issue is user feedback. Ultimately, we would love to see RiverTrail become part of JavaScript, as an open standard. However, we want to make sure that it does address the needs of web developers and their usability concerns. For this we depend on the web community. Try RiverTrail, build new things with it and tell us about your experience.

Rate this Article