Skip to content
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

cargo: emit less debug info, and compile all deps in optimized mode #3447

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

thoughtpolice
Copy link
Contributor

See commit messages for details.

@thoughtpolice thoughtpolice requested a review from yuja April 4, 2024 08:00
Copy link
Contributor

@yuja yuja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm conservative about changing the default build profile, but I'm not against this change if people like it.

Regarding debug = "line-tables-only", I don't think disk size is so important. The target directory will grow indefinitely anyway. If it breaks gdb, I would vote against it.

@martinvonz
Copy link
Member

Since dependencies rarely change, I would prefer to compile all dependencies in optimized mode and compile only the crates in the repo in debug mode. What do you think? Is that possible/easy to configure?

@yuja
Copy link
Contributor

yuja commented Apr 4, 2024

Since dependencies rarely change, I would prefer to compile all dependencies in optimized mode and compile only the crates in the repo in debug mode.

fwiw, I tried something like that for "pest", but it didn't help much. That's probably because the parsing code is generated by proc macro.

@thoughtpolice
Copy link
Contributor Author

thoughtpolice commented Apr 4, 2024

Since dependencies rarely change, I would prefer to compile all dependencies in optimized mode and compile only the crates in the repo in debug mode. What do you think? Is that possible/easy to configure?

Yes, that's exactly what the first change will do. The semantics are a bit weird but make sense; [profile.dev.package."*"] applies to all dependencies, while [profile.dev] will only apply to crates in the given repository. (I verfied this with --verbose where you can see opt-level=3 getting passed to dependent crates, but not jj crates.) So, this is exactly what we want. :)

@thoughtpolice
Copy link
Contributor Author

thoughtpolice commented Apr 4, 2024

The target directory will grow indefinitely anyway.

Yes, but anything to help fight off the nearly infinite disk space usage is nice IMO. Something is much better than nothing. :) Also, writing significantly less debug info does help compile times, though the opt-level=3 change offsets that a bit.

Frankly I would be much happier if Cargo could actually GC the target directory as a first-class feature, but that's a bit of a pipe dream, at least for now...

If it breaks gdb, I would vote against it.

Do you often use GDB for debugging? I admit, I nearly never use it for type-safe languages like Rust, but I guess that's maybe just because of my history in other compiled languages where I didn't need them or have DWARF symbols, so I was just stuck with fresh assembly code. Anything unsafe I just isolate and bang on and fuzz endlessly, manually. That's a bit "Back in my day I walked uphill both ways to get to school" though, so I get that it's not a great argument.

TBH, I've wanted to have specific settings of mine put in .cargo/config.toml before, but I don't want to force them on everyone else on the team. Maybe we could instead just have a few different "example files" under .cargo/, ignore the default .cargo/config.toml, and let people symlink their configuration of choice? Then we could have a .cargo/full-debug.toml that you can symlink into place. That might be nice.

Copy link
Member

@martinvonz martinvonz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's exactly what the first change will do.

Heh, I somehow missed that. Sorry.

insta.opt-level = 3
similar.opt-level = 3
[profile.dev.package."*"]
codegen-units = 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is what makes it so much slower. I agree with Yuya that the size of the binary is not important to optimize for.

I'll happily approve a PR that just sets opt-level = 3 for all dependencies and nothing else (but it's a significant change, so you might want to wait to hear from others too).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, codegen-units=1 has nearly no impact at all on compile times (or at least the fluxuations are minor), and also has almost no (repeatably measurable) impact on runtime for me, either. I included it for a more pedestrian reason: so that the dependencies in the development build more closely match the dependencies in the release build, where we do set that option. But I can drop it too, if we'd like.

Copy link
Contributor Author

@thoughtpolice thoughtpolice Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also, I want to be clear it is not the size of the final binaries that I am worried about with the line-tables-only change. It is the size of every intermediate artifact ever compiled — by rust-analyzer, by running nextest, from dependabot updates, etc. My development machine for jj has 1TB of space, but it's absurd that Cargo can eat almost +100GiB every two weeks for a single project. This will continue to get worse as we pile in more crates (but that's another discussion). I think that just building once in release profile and once in the dev profile will put you at 10GB of disk space usage... It piles up very fast.

There are other factors here, for example my machine uses mold for linking, but I suspect that this change would have a positive impact on non-mold users (where there is no parallelism, and debuginfo tends to have a disproportionate affect on link time). I also suspect that on an actual HDD where write times are 100x slower and random reads are slow and sequential will probably see improvements, too. But those are just speculation; I haven't tested them, though I'm happy to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my machine, codegen-units=1 on dev deps increases the build time from about 50s to about 60s. Since dependencies are rarely recompiled, I'm fine with either.

@PhilipMetzger
Copy link
Contributor

I'm fine with this, even if normal builds take a bit longer. The linetables change is nice for development but makes it harder to diagnose issues for users, so let's hope our dependencies don't break to much 🙏 .

@yuja
Copy link
Contributor

yuja commented Apr 5, 2024

Do you often use GDB for debugging?

Not often, but I occasionally do. Last time I used gdb was to debug libgit2 behavior. If I were new to jj codebase, and debugger didn't work, I would be confused.

@emesterhazy
Copy link
Contributor

+1 for the notion that it would be nice if debuggers still worked after this change. For what it's worth though, I'd also be fine if we just added a doc that discussed how to get the debugger working properly. It's not a simple as setting a breakpoint in an IDE since the tests run the CLI in a subprocess, so if the user also needs to build with a different profile that seems ok as long as it's documented with instructions.

@thoughtpolice thoughtpolice force-pushed the aseipp/push-lpvowkrkonwk branch from efc2afc to fd3d464 Compare April 10, 2024 16:35
@thoughtpolice thoughtpolice force-pushed the aseipp/push-lpvowkrkonwk branch from fd3d464 to cc99b80 Compare April 22, 2024 05:33
@thoughtpolice thoughtpolice force-pushed the aseipp/push-lpvowkrkonwk branch 2 times, most recently from 8e2e18e to 40b1b26 Compare May 7, 2024 17:00
@thoughtpolice thoughtpolice force-pushed the aseipp/push-lpvowkrkonwk branch from 40b1b26 to 1ee6f0b Compare May 14, 2024 00:06
Yuya noted the other day that `pest 2.7.9` seemed to cause testing slowdowns.
Out of curiosity, I decided to see how much `opt-level=0`, which is implied
by the default `dev` profile, costs us. This sets `opt-level=3`, and also sets
`codegen-units=1` as well, which should improve output object file size and
performance, too.

This dramatically speeds up testing by approximately 33% (45 -> 30s on my
machine.) However, it comes at the cost of a higher initial compile time for
dependencies; clean rebuilds nearly double now, from about 40s -> 1m30s. This is
probably a worthy tradeoff, though.

This is all tested on my 6-core/12-thread AMD Zen 3 desktop.

We could target more specific dependencies; we already do so with `insta`. But
compiling everything helps ensure we don't hit more performance cliffs when
some dependency introduces a codepath that behaves very poorly when unoptimized,
especially when they incrementally add up over time and the frog slowly boils.

We may want to tune Dependabot updates to be a little more spaced out (perhaps
once a week, if we can do so) in order to compensate for this.

Signed-off-by: Austin Seipp <[email protected]>
Change-Id: I6d84fac2b9d64d6ef1c8187f227cd1c1caa195ab
This causes `rustc` to only emit enough debuginfo to emit backtraces with
filepaths and line numbers, but nothing more. This has a massive impact on the
size of `target/` in practice; a clean rebuild of all dependencies (tested via
`cargo nextest run --workspace --no-run`) goes from ~5.5GiB to 2.1GiB.

This should help us stave off the dreaded sacrificial "delete `target/` to save
disk space" ritual that we occasionally must invoke (today I realized my `jj`
build dir was over 120GiB.)

Signed-off-by: Austin Seipp <[email protected]>
Change-Id: Ia1f31b87da89e59d77f54a3d79cb45113db215dc
@thoughtpolice thoughtpolice force-pushed the aseipp/push-lpvowkrkonwk branch from 1ee6f0b to 1e2d3ce Compare June 12, 2024 20:49
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.

5 participants