Parallelize LTO when compiling with GCC#313
Merged
Merged
Conversation
GCC 15 and 16 seem to default to using only 1 core when passing -flto, so it handles each partition sequentially while the rest of the system idles. GCC 10 and onward allow passing a number of threads as an option to the flag (i.e. -flto=4) or auto to use all available. Explicitly pass -flto=auto when compiling with GCC to ensure that it parallelizes WPA and LTO.
oznogon
added a commit
to oznogon/SeriousProton
that referenced
this pull request
May 2, 2026
GCC 15 and 16 seem to default to using only 1 core when passing -flto, so it handles each partition sequentially while the rest of the system idles. GCC 10 and onward allow passing a number of threads as an option to the flag (i.e. -flto=4) or auto to use all available. Explicitly pass -flto=auto when compiling with GCC to ensure that it parallelizes WPA and LTO.
oznogon
added a commit
to oznogon/SeriousProton
that referenced
this pull request
May 3, 2026
GCC 15 and 16 seem to default to using only 1 core when passing -flto, so it handles each partition sequentially while the rest of the system idles. GCC 10 and onward allow passing a number of threads as an option to the flag (i.e. -flto=4) or auto to use all available. Explicitly pass -flto=auto when compiling with GCC to ensure that it parallelizes WPA and LTO.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When building EE/SP with GCC and LTO enabled, GCC reports handling 95 LTRANS partitions. GCC 15 and 16 default to using only 1 core during linking when passed
-fltowith no option suffixed, so it handles each partition sequentially while the rest of the system idles.GCC 10 and onward allow passing a number of threads as an option to the flag (i.e.
-flto=4) orautoto use all available. Explicitly pass-flto=autowhen compiling with GCC to ensure that it parallelizes linking.This increases linking performance at a cost of increased memory usage. Build instructions should note that building on extremely resource-constrained systems (4GB RAM or less) might benefit from removing
=autoif building with LTO, although from testing compilation already uses more RAM (~5GB on 22 threads) than linking with parallelized LTO (~2.5GB on 22 threads, vs. ~0.2GB on 1 thread).Outcomes
On an Intel Ultra 7 155H (16 cores/22 threads, up to 4.8 GHz), 32GB RAM, Fedora 44, GCC 16.0.1, this PR reduces linking time on iterative builds (single-cpp-file changes) with LTO enabled by about 75%, from 1m22s to 21s.
The same percentile reduction was reproduced on a Core i5-6500T (4 cores/4 threads, up to 2.7GHz), 32GB RAM, Fedora 43, GCC 15.2.1, from 2m29s to 0m47s on iterative builds. This suggests that improvements don't necessarily scale past 4 threads. On the 155H and
-flto=4, the reduction was still about 62% (to 0m31).There was no significant change in full clean compile build times between master, this PR (
-flto=auto),-flto=4, and removing-flto. The improvements are entirely on iterative builds whereWith
-flto(master)Full clean build, compilation and linking with debug symbols (
~/git/daid/emptyepsilon-compile/ && rm -rf EmptyEpsilon/_build; cmake -S EmptyEpsilon -B EmptyEpsilon/_build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo && time cmake --build EmptyEpsilon/_build) on the Ultra 7 155H/32GB RAM/F44/GCC 16:Minor change, mostly linking
topshows load spread across all threads during compilation but concentrated on one thread during linking. Linking an iterative change alone takes almost as much time as a full recompilation with linking.With
-flto=auto(this PR)Full clean build, compilation and linking
Minor change, mostly linking
topshows load spread across all threads during both compilation and linking. Linking an iterative change takes about 1/4 as long as a full recompilation.With
-fltoremoved (no optimization)Full clean build, compilation and linking
Minor change, mostly linking
topshows load spread across all threads during compilation and is imperceptible during linking. Linking an iterative change without WPA or LTO takes almost no perceptible amount of time.