Skip to content

Investigate various Rust options effect on the MASM code size and cycle count #1065

@greenhat

Description

@greenhat

From https://midengroup.slack.com/archives/C08U8ANH5N3/p1775296630198239

I was looking into the code size issue for Rust-compiled programs, and aside from being uncertain which build profile we've been measuring against (I'm presuming dev DENNIS: release profile); I think we're missing some build options (or could be using better ones in some cases) that might help as well. For example:

  1. We aren't as precise about the release profile as we are dev, which means that we may be getting less-than-ideal defaults. I haven't dug deep to see what defaults might be pessimistic in our case, but it's something we should probably be more precise about.
  2. We are setting panic="abort", not panic="immediate-abort" in both profiles. The latter is now its own panic strategy, and can reduce code size. I think the old opt-in path for it no longer has any effect.
  3. We're using opt-level=1 for dev rather than opt-level="z". That may actually be desirable for development though - I'm not sure how bad debugging is with z to be honest, so it may be worth testing it out.
  4. We should probably try and measure whether opt-level="s" produces smaller binaries than opt-level="z" for us (as measured by the size of the resulting stripped MAST, not the Wasm binary)
  5. We're not setting strip=true for release builds, though I'm not sure if this would have any effect on code size ultimately - we should test to be sure.
  6. We're not setting lto=true. This could improve size considerably, as the linker can remove dead symbols, collapse duplicate code blocks, etc.
  7. We're not setting codegen-units=1. This improves the ability of LLVM to optimize across crates, which may also be useful for reducing size.
  8. We're not using the recently-added rust flag -Zfmt-debug=none. This one is not something we probably should set by default, as it can produce broken code in cases where something relies on specific output from Debug impls.
  9. We're not using build-std-features=optimize_for_size when using build-std. This would likely improve things significantly as well, since a lot of the code we pull in is from liballoc/libcore, and those are often build with a lot of optimizations for performance, not size.
  10. We may want to consider using twiggy to look for bloat in the Wasm produced by Rust/LLVM. Depending on what it finds, there may be actionable items there. Running cargo bloat --release --crates may also be useful
  11. We should try out using wasm-opt from the Binaryen toolkit to see if we can shrink size further, e.g. wasm-opt -g -Oz in.wasm out.wasm
  12. We should investigate to see if any LLVM options can be passed via rustc to enable more outlining and reduce the inlining threshold considerably
  13. We should avoid using #[inline]/#[inline(always)] in the SDK except in very specific cases. While this might reduce optimization opportunity, it might actually reduce code size quite a bit due to less duplication

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions