Rewrite the parallel raytracing example with rayon

One of the best parts about concurrency in Rust is using `rayon` and how
easy it makes parallelization of tasks, so it's the ideal example for
parallel Rust on the web! Previously we've been unable to use `rayon`
because there wasn't a way to customize how rayon threads themselves are
spawned, but [that's now being developed for us][rayon]!

This commit uses that PR to rewrite the `raytrace-parallel` example in
this repository. While not a perfect idiomatic representation of using
`rayon` I think this is far more idiomatic than the previous iteration
of `raytrace-parallel`! I'm hoping that we can continue to iterate on
this, but otherwise show it off as a good example of parallel Rust on
the web.

[rayon]: https://github.com/rayon-rs/rayon/pull/636
This commit is contained in:
Alex Crichton
2019-02-28 10:37:53 -08:00
parent f027bb2e09
commit eafc6024cc
6 changed files with 413 additions and 299 deletions

View File

@ -44,6 +44,7 @@ function run() {
// Configure various buttons and such.
button.onclick = function() {
button.disabled = true;
console.time('render');
let json;
try {
@ -82,22 +83,28 @@ class State {
this.running = true;
this.counter = 1;
this.interval = setInterval(() => this.updateTimer(), 100);
this.interval = setInterval(() => this.updateTimer(true), 100);
wasm.promise()
.then(() => {
this.updateTimer();
.then(data => {
this.updateTimer(false);
this.updateImage(data);
this.stop();
})
.catch(console.error);
}
updateTimer() {
updateTimer(updateImage) {
const dur = performance.now() - this.start;
timingVal.innerText = `${dur}ms`;
this.counter += 1;
if (this.wasm && this.counter % 3 == 0)
this.wasm.requestUpdate();
if (updateImage && this.wasm && this.counter % 3 == 0)
this.updateImage(this.wasm.imageSoFar());
}
updateImage(data) {
ctx.putImageData(data, 0, 0);
}
stop() {
@ -105,9 +112,9 @@ class State {
return;
console.timeEnd('render');
this.running = false;
pool = this.wasm.cancel(); // this frees `wasm`, returning the worker pool
this.wasm = null;
clearInterval(this.interval);
button.disabled = false;
}
}
@ -116,6 +123,5 @@ function render(scene) {
rendering.stop();
rendering = null;
}
rendering = new State(scene.render(parseInt(concurrency.value), pool, ctx));
pool = null; // previous call took ownership of `pool`, zero it out here too
rendering = new State(scene.render(parseInt(concurrency.value), pool));
}