Live data from Hacker News

JavaScript in Parallel: Web Workers and SharedArrayBuffer

50linesofco.de

41–50 of 74 posts

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#41

If multithread is a possibility for the future of javascript why not make promises and async multithread and keep the same syntax we are using now... What is there to gain with workers ? It seems to me like an unnecessary addition ... but I am interested in the point of view of specialists on the matter. I may be wrong, but promises and async are for me a great formalism upon which one could build a future version of…

Well for one workers do not share scope, and at the moment sharing memory between the two is quite difficult. Second is race conditions like @btilly explained.

Right now workers are mainly used for extreme situations and eventually make it into libraries that others use.

I have created a library called Task.js that surfaces this idea into a promise compatible interface where you can just convert a pure function into a worker function. The end result is a promise supported function thats sends the function to a worker with your provided args and resolves when its done (also supports multiple workers and automatic queuing).

https://github.com/icodeforlove/task.js

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#42
This is a very nice article! There's however a bug in the code, where it will "finish" when the last worker is done:

  if(msg.data.offset + msg.data.length === buffer.byteLength)
While you most likely want to wait for all workers to be done before showing the results. In this code however, the last worker will always finish last because it has more work to do (higher numbers).

It's often cheaper to scale horizontally, by spreading the work between physical machines, then to add more cores to a shared memory. So it's not such a big deal to have a single threaded program, and single threaded code is easier to reason about. SharedArrayBuffer will however be nice in JavaScript because it allows optimization is games and such, allowing you to have parallel for loops.

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#43
post #7

What do people actually use Web Workers for? The examples I've seen, including this one, seem contrived. I keep hoping they'll change it to allow background image manipulation, but I haven't seen much real progress in that front.

Anything that does significant work that would otherwise result in an unresponsive UI. For example code on the following page is compiled as you type, without a webworker this would give a very horrible user experience because compilation can take a long time for very large input - https://codemix.github.io/flow-runtime/#/try

[deleted]

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#44

What do people actually use Web Workers for? The examples I've seen, including this one, seem contrived. I keep hoping they'll change it to allow background image manipulation, but I haven't seen much real progress in that front.

I've used it for background image manipulation before. Paint the image to a canvas, then grab the imagedata off of it, split it into as many parts as you have threads, then use the "transferrableObjects" property of postMessage to zero-copy transfer the data to each worker to be processed, transferred back, and re-stitched together. It's pretty powerful and suprisingly easy to work with once you understand it. [0] is…

That's interesting but, AFAIK (and, believe me, I'd be happy to be corrected), what you can't do is create a canvas element (even one not attached to the DOM), and paint directly to it using the standard 2D context and drawing primitives.

Like I say, more than happy to be corrected, because that sort of thing would be incredibly helpful. Really, anything that lets you mess with a disconnected DOM in the background and then attach it in the foreground could be useful but (and, again, I'm very happy to be corrected), I don't think you can do this.

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#45
post #18

Earlier quoted context omitted.

I used WebWorkers for some math - basically lots of Fourier transforms, which took a few seconds to complete. I expected to instantiate a WebWorker with a function, and was surprised to discover you have to give it a separate JavaScript file. It is not easy to adopt.

You can just call toString on a function and Blob the string. You have to keep your head straight about the fact that scopes won't transfer (no closures), which is probably why the API doesn't do it for you.

Yeah, this ticked me off as well because the use of Web Workers feels extremely un-idiomatic, but what you've said makes sense. If you just passed a function it might dupe people into thinking closures would work or, and this is perhaps worse, force the standard down the route of copying all the values available in the current closure into the worker's scope, which just sounds like a terrible idea to me.

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#46
post #34

It is really how disappointing the options to share data with workers are in the browser. Combine the limited options options to transfer data quickly, and the limited API available in the worker itself (no version of a DOM, even a gutted one for doing measurements), it is no surprise how few opportunities to use them effectively there are. When it comes to transferring objects, it is so bad people are resorting to J…

(I'm the author of the article you cite.)

For the record, Chrome has been working on improving their postMessage performance as of M57 [1], so my benchmark should probably be re-run.

Assuming they end up in the same ballpark as Safari and Edge, the only browser for which stringification would still make sense is Firefox. (And maybe they have improved in the past year too. :))

But a lot of the conclusions from that article came from the fact that non-stringified postMessage perf was so bad in Chrome, which especially impacted performance on Android devices.

[1]: https://twitter.com/cramforce/status/824273332258209792

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#47

Earlier quoted context omitted.

I've used it for background image manipulation before. Paint the image to a canvas, then grab the imagedata off of it, split it into as many parts as you have threads, then use the "transferrableObjects" property of postMessage to zero-copy transfer the data to each worker to be processed, transferred back, and re-stitched together. It's pretty powerful and suprisingly easy to work with once you understand it. [0] is…

That's interesting but, AFAIK (and, believe me, I'd be happy to be corrected), what you can't do is create a canvas element (even one not attached to the DOM), and paint directly to it using the standard 2D context and drawing primitives. Like I say, more than happy to be corrected, because that sort of thing would be incredibly helpful. Really, anything that lets you mess with a disconnected DOM in the background an…

You're talking about OffscreenCanvas. It's available in Firefox and nowhere else:

https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCa...

Having said that, if you want fast image manipulation, you're probably better off doing direct manipulation of Uint8Clamped arrays anyway, since that can be much faster.

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#48
post #18

Earlier quoted context omitted.

I used WebWorkers for some math - basically lots of Fourier transforms, which took a few seconds to complete. I expected to instantiate a WebWorker with a function, and was surprised to discover you have to give it a separate JavaScript file. It is not easy to adopt.

You can just call toString on a function and Blob the string. You have to keep your head straight about the fact that scopes won't transfer (no closures), which is probably why the API doesn't do it for you.

I wonder if bundlers like WebPack could make life simpler here..

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#49

Earlier quoted context omitted.

That's interesting but, AFAIK (and, believe me, I'd be happy to be corrected), what you can't do is create a canvas element (even one not attached to the DOM), and paint directly to it using the standard 2D context and drawing primitives. Like I say, more than happy to be corrected, because that sort of thing would be incredibly helpful. Really, anything that lets you mess with a disconnected DOM in the background an…

You're talking about OffscreenCanvas. It's available in Firefox and nowhere else: https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCa... Having said that, if you want fast image manipulation, you're probably better off doing direct manipulation of Uint8Clamped arrays anyway, since that can be much faster.

And if you can get away with it and don't mind a lot of bit shifting, it's even better working with the Uint32array which packs all 3 colors and alpha into one element which reduces your loops by 4X

Re: JavaScript in Parallel: Web Workers and SharedArrayBuffer

#50

Earlier quoted context omitted.

I've used it for background image manipulation before. Paint the image to a canvas, then grab the imagedata off of it, split it into as many parts as you have threads, then use the "transferrableObjects" property of postMessage to zero-copy transfer the data to each worker to be processed, transferred back, and re-stitched together. It's pretty powerful and suprisingly easy to work with once you understand it. [0] is…

That's interesting but, AFAIK (and, believe me, I'd be happy to be corrected), what you can't do is create a canvas element (even one not attached to the DOM), and paint directly to it using the standard 2D context and drawing primitives. Like I say, more than happy to be corrected, because that sort of thing would be incredibly helpful. Really, anything that lets you mess with a disconnected DOM in the background an…

As the other commenter said, you are right that you can't work with canvas in the worker, but you can work directly with the array of image data which you'd often need to anyway for much processing.

I saw a library a while ago that was trying to re-implement the canvas primitives using only typed arrays so it was worker safe but I'm not sure what happened to it.

Post reply on HN