memorysafety/rav1d

Investigate/optimize code size

Opened this issue · 4 comments

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.

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.

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.

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?

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.