Skip to content

Conversation

@jordo
Copy link
Contributor

@jordo jordo commented Sep 25, 2024

Alternative to #97407 which runs wasm-opt with maximum shrink-level (2) / Oz.

@jordo jordo requested a review from a team as a code owner September 25, 2024 16:16
@adamscott
Copy link
Member

Performance-wise and size-wise, how does it stack to the alternative PR?

@jordo
Copy link
Contributor Author

jordo commented Sep 25, 2024

Performance wise, this shouldn't actually change anything ( I haven't verified with the same setup as previous and I may not have time to do an apples to apples comparison unfortunately). But this doesn't change any compiler and linker args. The only thing this changes is what optimization passes binaryen is running. This happens after wasm-ld in emscripten. By default emscripten just passes along the same optimization arg to wasm-opt with the addition of some manual passes: --strip-target-features --post-emscripten --low-memory-unused --zero-filled-memory --pass-arg=directize-initial-contents-immutable --mvp-features --enable-bulk-memory --enable-exception-handling --enable-multivalue --enable-mutable-globals --enable-reference-types --enable-sign-ext, but that doesn't necessarily have to be the case.

The only optimization pass that isn't guarded by a shrink level AND and an optimization level is merge-similar-functions, https://github.com/WebAssembly/binaryen/blob/ccef354cc8c0379e91b4dffb365fc69f616d6e25/src/passes/pass.cpp#L765C1-L768C4 . I haven't looked into the source of this particular optimization pass, but guessing by the name I don't think the pass is going to add a performance penalty in the name of optimizing output size. So that effectively means we're just getting all the existing optimizations (same performance) but a smaller wasm bundle. In fact, this may even be MORE performant due to some guards being behind opt lvl 3 OR shrink lvl 2, for example:

https://github.com/WebAssembly/binaryen/blob/ccef354cc8c0379e91b4dffb365fc69f616d6e25/src/passes/pass.cpp#L626C1-L628C4

I ran with debug output to verify what optimization passes binaryen is actually running and can confirm it's a different set. In fact, you can even go to O4 in wasm-opt. I tried that as well, but it resulted in a larger bundle so I didn't bother to profile that option any further.

This saves about 5% of the wasm size for us.

@adamscott
Copy link
Member

Are #97407 and this PR compatible?

@jordo
Copy link
Contributor Author

jordo commented Sep 27, 2024

I would say they are mutually exclusive, and I wouldn't bother merging this PR if #97407 is merged because then this is just superfluous. #97407 passes Oz to the compiler and linker, whereas this PR just passes to wasm-opt. Up to I guess whoever to decide where the best spot for performance vs size tradeoff line is. For myself Oz is probably just too much of a performance hit for our web builds, which we need to run efficiently, especially on low-end android devices.

That being said, this is probably the 'safer' of the two, as it shouldn't affect performance at all (compiler args are the same), and it does saves size. It may even increase performance, but I haven't had time to properly benchmark as we've just decided to run with it.

@dustdfg
Copy link
Contributor

dustdfg commented Sep 28, 2024

Didn't test this PR but expect it will do as best as manual wasm-opt call (saved ~10% of space for some people)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants