Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why are bevy executable so large? #1073

Closed
morr0ne opened this issue Dec 15, 2020 · 13 comments
Closed

Why are bevy executable so large? #1073

morr0ne opened this issue Dec 15, 2020 · 13 comments
Labels
A-Build-System Related to build systems or continuous integration

Comments

@morr0ne
Copy link

morr0ne commented Dec 15, 2020

After tinkering around with bevy for a bit I decided to run the this example.
After building in release mode with several optimizations: link-time optimization (lto) enable, codegen units set to 1, default linker (#1057), striping the binary
I noticed a resulting binary of 14.1 Mb.
Even after setting abort to panic and optimizing for size, I get a 10.1 Mb binary, which while being a big improvement is still pretty big for such a simple game

Running cargo-bloat doesn't help has 90%+ of the methods are discarded as too small

My questions then obviously are: Why is the executable so large? Can anything be done to fix it? What improvements can I make and what has to be improved on bevy?

I'm not a rust nor a game developing expert so forgive me if I'm asking something incredibly stupid

My config:
i5-8520u
940mx with priopetary nvidia drivers
Manjaro kde 20.2

@cart
Copy link
Member

cart commented Dec 15, 2020

Earlier in the project I'm pretty sure I had size-optimized binaries that were just slightly over 1 MB. At some point we regressed. I'm guessing it was probably this pr: #740, as we start linking to some pretty large non-rust binaries. It would be interesting to see if checking out the commit right before that pr cuts size-optimized binary size.

@cart
Copy link
Member

cart commented Dec 15, 2020

And if it does, the good news is that the approach there is a temporary measure. As soon as the pure-rust Naga shader compiler is ready we'll drop bevy-glsl-to-spirv.

@morr0ne
Copy link
Author

morr0ne commented Dec 15, 2020

Thanks for the fast response, I'll try compiling the same example before that commit

@morr0ne
Copy link
Author

morr0ne commented Dec 15, 2020

After reverting to this commit which seems to be the one just before #740 using the same optimizations I get a 9.1 Mb and a 5.3 Mb respectively. That's a huge difference for just one change. I'm definitely looking forward to naga but in the meantime is there no solution? That change was made to support android so it possible it could be disabled for other platforms? Also, Is it possible to entirely avoid a shader compiler and compile everything at compile time? Wouldn't that improve both size and speed? I'm no Vulkan expert but I roughly know how shaders work, would it be possible even if just some shaders are converted to spir-v at compile time?

@cart
Copy link
Member

cart commented Dec 15, 2020

That change was made to support android so it possible it could be disabled for other platforms?

We also support the shaderc compiler on some platforms (ios + web). The main problem is that it requires a more complicated build system. Especially on windows, it requires non-standard dependencies like Ninja + python. I want Bevy to be as "plug and play" as possible. It shouldn't require a bunch of manual setup.

I would like to make it possible to opt-in to shaderc on any platform, but there are some cargo corner cases that make it non-trivial. We need it to be the default on some platforms, but opt-in on other platforms (which doesn't quite work, but it soon will rust-lang/cargo#7914).

Also, Is it possible to entirely avoid a shader compiler and compile everything at compile time? Wouldn't that improve both size and speed? I'm no Vulkan expert but I roughly know how shaders work, would it be possible even if just some shaders are converted to spir-v at compile time?

Yup this is absolutely a scenario I want to support. You can already do this with simple shaders (the shader type supports pre-compiled spirv), but the ShaderDef system that bevy uses to compile shader variants based on component/assets values requires a bit more thought to allow pre-compiling (as the ShaderDefs can change at compile time). You either need to brute-force compile every permutation (which will be infeasible for shaders with many variants) or you need to enumerate the variants you know you need ahead of time.

@morr0ne
Copy link
Author

morr0ne commented Dec 15, 2020

My understanding is that Naga will (hopefully) resolve all this problems.
Regarding compile shaders at compile time are there examples available? Especially about enumerating them. Would it make sense to provide an example of breakout with compile time shaders?

@cart
Copy link
Member

cart commented Dec 15, 2020

Hmm adding precompiled "built in" shaders is non-trivial because of the whole ShaderDef thing mentioned above. I'm planning on making the built-in shaders have many ShaderDefs, which will produce the combinatorics explosion mentioned above. So doing that now feels a bit short-sighted.

I think my ideal solution is: cheap-to-include shader compiler (ex: Naga) plus optional pre-compiled SPIRV caching (maybe users opt in specific permutations, maybe we auto-cache any permutation used by the game).

Rather than go in a direction that conflicts with the "ideal solution" in the short term interest of smaller binaries, I'd rather find some other workaround (such as sorting out a way for you to use shaderc).

@morr0ne
Copy link
Author

morr0ne commented Dec 15, 2020

Binary size problem I feel like it will be mostly solved by switching to Naga, which right now seems the most promising pure rust shader compiler, especially considering it's made by the same team working on gfx/wgpu

I believe that the ShaderDefs implementation should be thought out more, spir-v caching and any other type of shader optimization may be of a small impact on binary size and speed for such simple projects but at a big scale it could have really big impact

Also some people might prefer shaderc over Naga anyway

The best solution is probably to give as much choice as possible to the user, by providing many ShaderDefs options and the ability to change shader compiler

After this gets resolved, would it be possible to provide shaderc on all platforms?
How would I switch to shaderc right now?

@cart
Copy link
Member

cart commented Dec 15, 2020

I believe that the ShaderDefs implementation should be thought out more, spir-v caching and any other type of shader optimization may be of a small impact on binary size and speed for such simple projects but at a big scale it could have really big impact

Fully agreed. Pre-compiling shaders is an important feature.

After this gets resolved, would it be possible to provide shaderc on all platforms?

yup!

How would I switch to shaderc right now?

I would clone a local copy of bevy, make the relevant changes, and use that:

@morr0ne
Copy link
Author

morr0ne commented Dec 15, 2020

Would it make sense to add this features to the roadmap as they seem pretty important or are they already there and i just missed them?

@cart
Copy link
Member

cart commented Dec 15, 2020

Probably 😄

Right now the roadmap isn't a perfect reflection of everything we plan to do. Its largely a way to communicate what we're currently working on and a few "big ticket" items on the horizon.

@morr0ne
Copy link
Author

morr0ne commented Dec 15, 2020

I see, I'll dig around in the source maybe I can contribute some myself :D

Since I'm still learning my way around bevy I'll probably stick a bigger binaries for now but thanks for the really fast response, bevy is exactly what I'm looking for in a game engine, and seeing how open and active this project is compared to others is really promising, keep up the good work!

Edit: I'll leave this issue open in case someone has the same size problems or wants add something to the discussion

@Moxinilian Moxinilian added A-Build-System Related to build systems or continuous integration question labels Dec 17, 2020
@CleanCut
Copy link
Member

We need it to be the default on some platforms, but opt-in on other platforms (which doesn't quite work, but it soon will rust-lang/cargo#7914).

Maybe very soon! rust-lang/cargo#8997

@bevyengine bevyengine locked and limited conversation to collaborators Jul 14, 2021
@cart cart closed this as completed Jul 14, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
A-Build-System Related to build systems or continuous integration
Projects
None yet
Development

No branches or pull requests

4 participants