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 Jun 5, 2019
1 parent cf2a42c commit 2e1030e
Show file tree
Hide file tree
Showing 7 changed files with 418 additions and 302 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,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/rayon-rs/rayon' }
rayon-core = { git = 'https://github.com/rayon-rs/rayon' }
7 changes: 2 additions & 5 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,11 @@ jobs:
steps:
- template: ci/azure-install-rust.yml
parameters:
toolchain: nightly-2019-04-01
toolchain: nightly
- template: ci/azure-install-sccache.yml
- script: rustup component add rust-src
displayName: "install rust-src"
- script: |
set -e
curl -L https://github.com/japaric/xargo/releases/download/v0.3.13/xargo-v0.3.13-x86_64-unknown-linux-musl.tar.gz | tar xzf -
echo "##vso[task.prependpath]$PWD"
- script: cargo install xargo
displayName: "install xargo"
- script: |
set -e
Expand Down
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.22"
rayon = "1.0.3"
rayon-core = "1.0.3"
raytracer = { git = 'https://github.com/alexcrichton/raytracer', branch = 'update-deps' }
wasm-bindgen = { version = "0.2.45", features = ['serde-serialize'] }
wasm-bindgen-futures = "0.3.22"
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(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));
}
Loading

0 comments on commit 2e1030e

Please sign in to comment.