From d4aed8145b5478d62308319d2ad849e2a1e371db Mon Sep 17 00:00:00 2001 From: Ivan Boldyrev Date: Sat, 9 Sep 2023 23:45:31 +0400 Subject: Wasm32 SIMD implementation This code is based on rust_sse2.rs of the same distribution, and is subject to further improvements. Some comments are left intact even if their applicability is questioned. SIMD implementation is gated by `wasm32-simd` feature, portable version is used otherwise. Performance measurements with a primitive benchmark with ~16Kb of data: | M1 native | 11,610 ns | | M1 WASM SIMD | 13,355 ns | | M1 WASM | 22,037 ns | | x64 native | 6,713 ns | | x64 WASM SIMD | 11,985 ns | | x64 WASM | 25,978 ns | wasmtime v12.0.1 was used on both platforms. Closes #187. --- build.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'build.rs') diff --git a/build.rs b/build.rs index 3f23161..84717f9 100644 --- a/build.rs +++ b/build.rs @@ -21,6 +21,10 @@ fn is_no_neon() -> bool { defined("CARGO_FEATURE_NO_NEON") } +fn is_wasm32_simd() -> bool { + defined("CARGO_FEATURE_WASM32_SIMD") +} + fn is_ci() -> bool { defined("BLAKE3_CI") } @@ -91,6 +95,10 @@ fn is_armv7() -> bool { target_components()[0] == "armv7" } +fn is_wasm32() -> bool { + target_components()[0] == "wasm32" +} + fn endianness() -> String { let endianness = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap(); assert!(endianness == "little" || endianness == "big"); @@ -285,6 +293,13 @@ fn build_neon_c_intrinsics() { build.compile("blake3_neon"); } +fn build_wasm32_simd() { + assert!(is_wasm32()); + // No C code to compile here. Set the cfg flags that enable the WASM SIMD. + // The regular Cargo build will compile it. + println!("cargo:rustc-cfg=blake3_wasm32_simd"); +} + fn main() -> Result<(), Box> { // As of Rust 1.80, unrecognized config names are warnings. Give Cargo all of our config names. let all_cfgs = [ @@ -341,6 +356,10 @@ fn main() -> Result<(), Box> { build_neon_c_intrinsics(); } + if is_wasm32() && is_wasm32_simd() { + build_wasm32_simd(); + } + // The `cc` crate doesn't automatically emit rerun-if directives for the // environment variables it supports, in particular for $CC. We expect to // do a lot of benchmarking across different compilers, so we explicitly -- cgit v1.2.3