Add wasm support via navigator.hardware_concurrency()#89
Conversation
|
This should be gated by a feature. It also probably will cause problems where libraries will attempt to spawn threads, so this is a breaking change in a way. |
|
Very cool! I wonder, is it easy-ish to do without the dependencies? It's just wanting to call a single function, I don't know if we can do so with a smaller footprint, and if it's worth it. Another thought, wasm doesn't necessarily mean "browser", right? It could also be a WASI target, and this will break that? |
|
Yes there‘s wasm outside the browser, there‘s wasm in the browser, there‘s wasi and wasi in the browser. So those need to be handled differently (so 3 cases in total, maybe a 4th if you consider emscripten). However this will break many things regardless of that, as many libraries will start spawning threads if num_cpus > 1. So this should probably only ever return something other than 1 for now if you explicitly activate some wasm-threads feature (in addition to the wasm-web feature or so to specify that you are even targeting a browser). |
I don't understand why this is a problem. If a user is asking for the number of CPUs so they can choose how many threads to spawn, then it shouldn't break people if we give them a more accurate number. Otherwise, adding support for any new target would be a breaking change. |
|
I was hesitant to add a feature-gate for this since the crate doesn't currently have any. I've seen other crates use [1] https://github.com/grovesNL/glow/blob/master/Cargo.toml#L18-L19 Should the default for wasm32 stay as 1 unless some combination of features is enabled? What cfg flags would you recommend for gating this implementation to only wasm32-unknown-unknown in the browser? |
No, because wasm32 is the only target that has std despite not really having working threads (or and OS really, so almost all of std panics). I consider this a mistake, wasm32-unknown-unknown should‘ve been a no_std target. But it isn‘t so we‘ll have to live with that and gate spawning threads in libraries behind appropriate cfg‘s. However I know that many libraries implicitly work for wasm32 because they don‘t spawn any threads when num_cpus is 1. So yes, they should probably have appropriate cfgs, but don‘t. So this will break libraries. |
That's unfortunate, but I don't feel that situation should prevent |
|
I agree this should be behind a feature gate - not every wasm32 build is related to wasm-bindgen - but otherwise I'd love to see this merged. |
|
I've opened an alternative PR in #103 with few improvements. |
Currently,
num_cpus::get()always returns 1 on web assembly targets.Although wasm is typically limited to single-threaded execution itself, it is possible to make use of multiple CPUs via Web Workers
On the
wasm32-unknown-unknownplatform, using the wasm_bindgen and web_sys crates, we can get a more accurate result by usingnavigator.hardware_concurrency()to get the number of CPUs on a system.I tried to keep the code as similar as possible to the existing library.
Reference:
[1] https://developer.mozilla.org/en-US/docs/Web/API/NavigatorConcurrentHardware/hardwareConcurrency
[2] https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Navigator.html#method.hardware_concurrency
Testing
I created a very basic test based on the wasm-bindgen Hello World
The
Cargo.tomlis the same as upstream, but also has the 'Navigator' feature enabled for web-syslib.rs:
I build the test crate for wasm without a bundler as follows:
I also have a basic index.html page that I copy into the
pkgdirectory that wasm-pack creates:I then start an http server in the
pkgdirectory and browse to it.Previously,
num_cpus::get()would return 1, but now it correctly returns 8 on my system.This is my first Rust contribution so please let me know if I should change anything.
Thanks,
Michael