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 13, 2019
1 parent f027bb2 commit eafc602
Show file tree
Hide file tree
Showing 6 changed files with 416 additions and 302 deletions.
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.1.0"
rayon-core = "1.5.0"
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 eafc602

Please sign in to comment.