-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Big static array causes rlib to bloat in size #136519
Comments
why would you expect such a static to not be present in the binary, exactly? |
Because zeroed statics can be put at If we change the immutable static above into a mutable static, it gets to be stored in |
Edit: It seems both gcc and clang does place the static zeroed arrays on |
@adwinwhite Thank you! That helps narrow down what I'm looking for. For this C: char BUFFER[1 << 29] = {};
int main() {
} I get this in the compiled object from clang:
But with this code diff: -char BUFFER[1 << 29] = {};
+const char BUFFER[1 << 29] = {}; I see this object diff: .type BUFFER,@object # @BUFFER
- .bss
+ .section .rodata,"a",@progbits
.globl BUFFER
.p2align 4, 0x0 That will have the matching effect, right? So this is actually a consistent implementation between clang and rustc, it's just different defaults, right? |
We can put such a zeroed array in bss as an optimization, I suppose, but it seems we would be deviating from clang in doing so. |
I'm not sure if the comparison with assembly/object files produced by Clang is appropriate. The original issue said "the final executable is unaffected" so it seems that the final codegen is already as expected. But rlib files also contain a lot of metadata, not just LLVM IR and/or object files. In particular, it contains the values of constants/statics that may be needed by constant evaluation in dependent crates. I suspect that the large size of the rlib may be caused by this representation of the static, because there's probably no equivalent of |
Then I suppose if I check the |
using a run-length encoding type of thing for static arrays with homogenous values seems reasonable, I suppose, but I wonder if it will cause some sort of linking errors... |
Yes. The rlib contains a |
huh. $ cargo build
Compiling const-init-size v0.1.0 (/home/jubilee/rust/const-init-size)
warning: static `BUFFER` is never used
--> src/lib.rs:1:8
|
1 | static BUFFER: [u8; 1 << 29] = [0; 1 << 29];
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default
ls Building [ ] 0/1: const-init-size
warning: `const-init-size` (lib) generated 1 warning
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.20s
$ ls -lh target/debug/
total 1.1G
drwxr-xr-x 2 jubilee jubilee 4.0K Feb 6 17:26 build
drwxr-xr-x 3 jubilee jubilee 4.0K Feb 6 20:42 deps
drwxr-xr-x 2 jubilee jubilee 4.0K Feb 6 17:26 examples
drwxr-xr-x 6 jubilee jubilee 4.0K Feb 6 20:41 incremental
-rw-r--r-- 1 jubilee jubilee 119 Feb 6 20:41 libconst_init_size.d
-rw-r--r-- 2 jubilee jubilee 1.1G Feb 6 20:42 libconst_init_size.rlib
$ helix .
$ cargo build
Compiling const-init-size v0.1.0 (/home/jubilee/rust/const-init-size)
warning: static `BUFFER` is never used
--> src/lib.rs:1:12
|
1 | static mut BUFFER: [u8; 1 << 29] = [0; 1 << 29];
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: `const-init-size` (lib) generated 1 warning
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.28s
$ ls -lh target/debug/
total 513M
drwxr-xr-x 2 jubilee jubilee 4.0K Feb 6 17:26 build
drwxr-xr-x 3 jubilee jubilee 4.0K Feb 6 20:43 deps
drwxr-xr-x 2 jubilee jubilee 4.0K Feb 6 17:26 examples
drwxr-xr-x 6 jubilee jubilee 4.0K Feb 6 20:41 incremental
-rw-r--r-- 1 jubilee jubilee 119 Feb 6 20:41 libconst_init_size.d
-rw-r--r-- 2 jubilee jubilee 513M Feb 6 20:43 libconst_init_size.rlib I guess |
@workingjubilee indeed. You can |
Sorry I probably have reduced that example too much. It was also pretty late, when I submitted this. struct Buff(std::cell::UnsafeCell<[u8;1 << 29]>);
unsafe impl Send for Buff { }
unsafe impl Sync for Buff { }
static BUF : Buff = unsafe { std::mem::zeroed() }; Essentially this is about being able to "reserve" memory in the data section. One reason for why, is to have memory that is close addresswise to text/data. Useful when hotpatching as it allows to use 32bit relative jumps & refer to existing data symbols from hotpatched functions. Relocations targeting data symbols are generally 32 bit, at least on windows. |
I don't think there's any requirement that these things are mapped next to each other. |
Nonetheless, @nebulark I am curious why the size in the rlib matters to you, given that it does not seem to affect your use case? |
For me personally it does not matter that much. It just takes some additional disk space needlessly, which it a very minor annoyance. |
Aha, okay! I mostly wanted to make sure I wasn't missing something important. |
That can be fixed! |
Going to perf ideas here: #137152 |
A big static array inside a library causes the generated lib file to bloat in size, even if it is zero initialized.
I tried this code:
I would expect that this would not affect the size of library.
Instead this causes the library to include a LOT of 0s, increasing the size in this example to over 1GB.
The final executeable is unaffected, only the .rlib file bloats.
Meta
This happens in stable and nightly
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: