Skip to content

Commit

Permalink
Rewrite the parallel raytracing example with rayon
Browse files Browse the repository at this point in the history
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]: rayon-rs/rayon#636
  • Loading branch information
alexcrichton committed Mar 22, 2019
1 parent 0631182 commit a77eecd
Show file tree
Hide file tree
Showing 6 changed files with 425 additions and 297 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,5 @@ wasm-bindgen = { path = '.' }
wasm-bindgen-futures = { path = 'crates/futures' }
js-sys = { path = 'crates/js-sys' }
web-sys = { path = 'crates/web-sys' }
rayon = { git = 'https://github.com/cuviper/rayon', branch = 'custom-spawn' }
rayon-core = { git = 'https://github.com/cuviper/rayon', branch = 'custom-spawn' }
2 changes: 2 additions & 0 deletions examples/raytrace-parallel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ crate-type = ["cdylib"]
console_error_panic_hook = "0.1"
futures = "0.1"
js-sys = "0.3.17"
rayon = "1.0.3"
rayon-core = "1.0.3"
raytracer = { git = 'https://github.com/alexcrichton/raytracer', branch = 'update-deps' }
wasm-bindgen = { version = "0.2.40", features = ['serde-serialize'] }
wasm-bindgen-futures = "0.3.17"
Expand Down
24 changes: 15 additions & 9 deletions examples/raytrace-parallel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function run() {

// Configure various buttons and such.
button.onclick = function() {
button.disabled = true;
console.time('render');
let json;
try {
Expand Down Expand Up @@ -82,32 +83,38 @@ 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() {
if (!this.running)
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;
}
}

Expand All @@ -116,6 +123,5 @@ function render(scene) {
rendering.stop();
rendering = null;
}
rendering = new State(scene.render(concurrency.value, pool, ctx));
pool = null; // previous call took ownership of `pool`, zero it out here too
rendering = new State(scene.render(concurrency.value, pool));
}
Loading

0 comments on commit a77eecd

Please sign in to comment.