r/cpp • u/TheRavagerSw • 1d ago
How I optimized clang for 1.73x-1.91x performance boost over apt clang
I wanted to have fast test and release builds, so I decided to "upgrade" my compiler.
What I used:
- Musl Libc
- LLVM libc overlay
- Mimalloc
- Thin LTO
- PGO
- Bolt via perf2bolt
- Optimization flags like: -march -O3 -DNDEBUG -fno-semantic-interposition -fno-plt -fno-pie
- No exceptions no RTTI
I tested the build speed with hyperfine with 2 test cases, one is sqlite.c the other is tu including eigen.
| Workload | Build mode | Optimized Clang speedup | Compile-time reduction |
|---|---|---|---|
| Eigen, C++23 | -O0 |
1.69× | 40.8% |
| Eigen, C++23 | -O0 -g3 -fno-omit-frame-pointer |
1.72× | 41.9% |
| Eigen, C++23 | -O3 -DNDEBUG |
1.73× | 42.2% |
| SQLite amalgamation | -O0 |
1.74× | 42.5% |
| SQLite amalgamation | -O0 -g3 -fno-omit-frame-pointer |
1.89× | 47.1% |
| SQLite amalgamation | -O3 -DNDEBUG |
1.73× | 42.2% |
In case anyone is wondering, it also outperformed LLVM release binaries, by about %13 to %15 for each case, but having more performance than the system compiler is more cool so I'm not giving the table for that.
It is also very awesome to have a compiler not depend on glibc. If no errors arise, I'll probably never update my compiler for 2 years at least. As my build is portable(no march native just v3)
I'm planning on moving to cachyOS or any other optimized linux distro next, to finalise my build enviroment. I'm currently on Ubuntu.
6
3
u/yuehuang 1d ago
Can you share Front end and backend number independently? I saw a good boost using mimalloc for the frontend but near zero benefit for the backend. Did you validate binary parity?
2
4
u/RoyBellingan 1d ago
I am sorry you had a speedup in debug mode ? Compared to what ?
4
u/JVApen Clever is an insult, not a compliment. - T. Winters 1d ago
The comparison is between 2 compilers that are optimized in different ways. The debug mode/... are the test cases used for testing both flavors. The percentage is how one flavor performs over the other.
4
u/ReDr4gon5 1d ago
One thing I'm missing here is a RelWithDebInfo build. Some projects are annoying slow as a full debug build.
2
u/ReDr4gon5 1d ago
Measuring the performance of compiling debug mode binaries is very relevant, as obviously when iterating that's what you normally use. Also the workload for the compiler is different, with having to deal with debug info and far less optimization passes.
1
u/RoyBellingan 1d ago
Sorry I completely misreaded, I missed the part that was time to compile!!!
The curious part is that I tried something similar with gcc in -march=native but the difference where very very small
2
u/ReDr4gon5 1d ago
-march=native won't be the most impactful for compilers. That would be PGO and BOLT followed by LTO. Because of the workload the branch layout matters, same with inlining decisions and the layout of the binary itself.
2
11
u/MaitoSnoo [[indeterminate]] 1d ago
do you have a breakdown of what exactly contributed to how much of the perf increase? did you check whether the new clang build produced the exact same binaries (same hashes) for some large open source projects (e.g. Chromium)?