memorysafety / rav1d

An AV1 decoder in Rust.
BSD 2-Clause "Simplified" License
335 stars 22 forks source link

Investigate/optimize code size #809

Open randomPoison opened 7 months ago

randomPoison commented 7 months ago

Our code size is roughly 10x that of dav1d. We need to investigate why our code size is so much larger, and potentially optimize our code to generate a smaller binary.

randomPoison commented 7 months ago

One thing to look into here is updating our version of rustc, since newer versions of the compiler have additional code size improvements for the standard library.

kkysen commented 7 months ago

A stripped dav1d binary with panic = "abort" is 3.5M, while a C libdav1d.so is 2.8M along with 54k for dav1d. librav1d.a is large, but it contains LLVM bitcode and isn't a shared library. So code size isn't so much larger (not 10x for sure). I think a lot of the increase is in .rodata, which is 418k in rav1d and only 144k in dav1d, which might be from changing lazily initialized static mut data into const fn-initialized non-mut statics, as previously those data were all zero-initialized initially.

negge commented 7 months ago

while a C libdav1d.so is 2.8M

Hi @kkysen, I am seeing a significantly smaller C shared library:

negge@arm1:~/git/dav1d/build# ls -l src/libdav1d.so.7.0.0
-rwxr-xr-x 1 negge negge 844672 Mar 14 16:43 src/libdav1d.so.7.0.0
negge@arm1:~/git/dav1d/build# strip src/libdav1d.so.7.0.0
negge@arm1:~/git/dav1d/build# ls -l src/libdav1d.so.7.0.0
-rwxr-xr-x 1 negge negge 739576 Mar 15 23:02 src/libdav1d.so.7.0.0

Can you please clarify what you mean by C libdav1d.so?

Similarly, the libdav1d.a I get when building with the latest rustc 1.76.0-nightly is 23MB (!) and still 12MB when stripped:

negge@arm1:~/git/rav1d# ls -lh target/aarch64-unknown-linux-gnu/release/librav1d.a 
-rw-r--r-- 2 negge negge 23M Mar 14 16:40 target/aarch64-unknown-linux-gnu/release/librav1d.a
negge@arm1:~/git/rav1d# strip target/aarch64-unknown-linux-gnu/release/librav1d.a
negge@arm1:~/git/rav1d# ls -lh target/aarch64-unknown-linux-gnu/release/librav1d.a 
-rw-r--r-- 2 negge negge 12M Mar 15 23:07 target/aarch64-unknown-linux-gnu/release/librav1d.a

This is 11591674 / 739576 = 15.67x larger binary by my calculations. How do I build a shared library for rav1d?

kkysen commented 7 months ago

librav1d.a contains a ton of LLVM bitcode I believe, that's why it's so big. We haven't set up librav1d.so yet, so I compared the size of the final dav1d binary, which should be similar. I compared that to the C dav1d binary and libdav1d.so library. I realize I forgot to strip libdav1d.so before, so now I get 1958336. Rust's dav1d is 3469160.

❯ /bin/ls -alF build/src/libdav1d.so.6.8.0 target/release/dav1d
-rwxrwxr-x 1 kkysen kkysen 1958336 Mar 15 12:13 build/src/libdav1d.so.6.8.0*
-rwxrwxr-x 2 kkysen kkysen 3469160 Mar 15 11:38 target/release/dav1d*

This is on x86_64-unknown-linux-gnu. I didn't check aarch64-unknown-linux-gnu yet, which might be smaller since there's less assembly versions.