Skip to content

Support SIMD on the Emscripten target - #50

Open
guybedford wants to merge 1 commit into
NoXF:masterfrom
guybedford:emscripten-simd
Open

guybedford wants to merge 1 commit into
NoXF:masterfrom
guybedford:emscripten-simd

Conversation

@guybedford

Copy link
Copy Markdown

Today build.rs has no wasm32 arm, so libwebp is built as plain C instead of SIMD there.

This adds support for wasm32-unknown-emscripten, along with the SSE intrinsics flags. Emscripten lowers SSE2 and SSE4.1 intrinsics to wasm simd128 through its emulation headers, and cpu.h derives WEBP_HAVE_SSE2/WEBP_HAVE_SSE41 from the compiler's __SSE2__/__SSE4_1__.

Note also that the vendored libwebp still selects its wasm CPU-info path on the legacy EMSCRIPTEN macro, which emcc no longer defines - libwebp updated use to __EMSCRIPTEN__ in v1.6.0-167 (53394835). Until the submodule moves past that commit, -DEMSCRIPTEN is needed in CFLAGS additionally, but I didn't want to hard-code that here since it will be ironed out in the next release and can be set manually in the mean time.

All tests are passing on Node.js, to run them, first set env vars:

export RUSTFLAGS="-Ctarget-feature=+simd128 -Clink-arg=-sNODERAWFS -Clink-arg=-sALLOW_MEMORY_GROWTH -Clink-arg=-sSTACK_SIZE=1048576"
export EMCC_CFLAGS="-msimd128 -DEMSCRIPTEN"
export CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER=node

Then run:

cargo test --target wasm32-unknown-emscripten --no-default-features --features std

In terms of performance, decoding a 4 MP lossy WebP went from 141 ms (plain C) to about 105 ms with the SSE2 paths active, with identical output.

Emscripten lowers the SSE2 and SSE4.1 intrinsics to wasm simd128, and
cpu.h derives WEBP_HAVE_SSE2/SSE41 from the compiler's __SSE2__ and
__SSE4_1__, so passing -msimd128 -msse2 (and -msse4.1 with the sse41
feature) when the Rust target has the simd128 feature is all that is
needed.

The vendored libwebp still selects its wasm CPU-info path on the legacy
EMSCRIPTEN macro that emcc no longer defines; libwebp moved to
__EMSCRIPTEN__ in v1.6.0-167 (53394835). Until the submodule is past that,
-DEMSCRIPTEN in CFLAGS is additionally needed for the SSE2 paths to be
selected at runtime.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant