[PATCH 0/5] Improve make and make check parallelism
Adhemerval Zanella
adhemerval.zanella@linaro.org
Fri Jun 12 16:34:03 GMT 2026
One thing that has bothered me for some time is that neither 'make' nor
'make check' scales well with the number of cores: although each
subdirectory builds with full internal parallelism, the top-level
recursion is marked .NOTPARALLEL and runs the sub-makes strictly one at
a time.
Every subdirectory's compile tail and link step therefore leaves most
cores idle, and the constant additions to the testsuite keep making it
worse. Profiling the check phase also showed that some of the tests-special
are among the main culprits, most notably check-installed-headers, which
performs dozens of serial compiler invocations per installed header.
This series makes the subdirectory recursion run in parallel while
encoding the ordering the serial recursion relied on as explicit
dependencies:
1. scripts/gen-sorted.awk also emits the dependency edges it already
collects from the Depend files, so the parent makefile can use
them as real rules instead of a flattened total order.
2. The top-level Makefile drops .NOTPARALLEL. The subdirectories
that generate shared files consumed by the rest of the build run
serially first (csu, plus mach and hurd on Hurd), the Depend
edges become rule dependencies, elf stays last (its rtld link
consumes the aggregated libc_pic.a), pass barriers keep others
after lib and tests after others, and the subdirectory-built
files that top-level rules list as prerequisites get order-only
edges.
3. elf is no longer forced last for the others and tests passes,
where the pass barriers already provide everything it needs.
4. The container testroot, which performs a full DESTDIR
installation, is no longer created when run-built-tests=no, since
no container test will run.
5. check-installed-headers compiles each header through its own
intermediate target so the compiler invocations spread across the
jobserver; the per-subdirectory .out aggregates the results in
the original order, so its contents and the test results are
unchanged.
The series does not aim to improve 'make check' with
run-built-tests=yes: subdirectories such as nptl require their tests
not to run in parallel.
Build results are unchanged: all built objects, archives, and shared
objects are bit-identical to the serial build across repeated clean
parallel builds, the installed tree layout is identical, and the
tests.sum results are identical. Since most of the possible failure
modes are races, the series was validated with repeated from-scratch
builds on x86_64-linux-gnu (24 threads), aarch64-linux-gnu (80 cores).
Benchmarks (cumulative; each percentage is relative to the previous
row, the first patch only adds data and acts as the baseline):
x86_64: Ryzen 5900 / 12c/24t
gcc 16.1.1 / ld 2.46 / gnumake 4.3 | targetting x86_64-linux-gnu
Commit | make | make check
----------------------------------------------------------------------|----------------------|------------------------------------------
scripts/gen-sorted.awk: Also emit the subdirectory dependency edges | 1m18,728s | 6m14,957s
Makefile: Run the subdirectory recursion in parallel | 1m01,713s (-21.6%) | 3m10,413s (-49.2%)
Makefile: Do not force elf last for the others and tests passes | 1m00,562s (-1.9%) | 3m01,644s (-4.6%)
Makefile: Do not install the container testroot if not running tests | 1m00,703s (+0.2%) | 2m49,552s (-6.7%)
Run check-installed-headers concurrently for each header | 1m00,598s (-0.2%) | 2m50,389s (+0.5%)
----------------------------------------------------------------------|----------------------|------------------------------------------
aarch64: Neoverse-N1 / 80c
gcc 15.2.1 / ld 2.45 / gnumake 4.3 | targetting aarch64-linux-gnu
Commit | make | make check
----------------------------------------------------------------------|----------------------|------------------------------------------
scripts/gen-sorted.awk: Also emit the subdirectory dependency edges | 1m45.251s | 14m46.183s
Makefile: Run the subdirectory recursion in parallel | 0m56.703s (-46.1%) | 04m58.726s (-66.3%)
Makefile: Do not force elf last for the others and tests passes | 0m53.887s (-5.0%) | 04m23.790s (-11.7%)
Makefile: Do not install the container testroot if not running tests | 0m54.801s (+1.7%) | 04m01.574s (-8.4%)
Run check-installed-headers concurrently for each header | 0m54.978s (+0.3%) | 03m02.405s (-24.5%)
----------------------------------------------------------------------|----------------------|------------------------------------------
I am stil running multiple sequential make check builds for multiple
ABIs to check if there are some missing race condition that I have not
spotted yet (I caught some running on the 80c aarch64 box).
Adhemerval Zanella (5):
scripts/gen-sorted.awk: Also emit the subdirectory dependency edges
Makefile: Run the subdirectory recursion in parallel
Makefile: Do not force elf last for the others and tests passes
Makefile: Do not install the container testroot if not running tests
Run check-installed-headers concurrently for each header
Makefile | 163 +++++++++++++++++++++++++++++++++++++----
Rules | 38 +++++++---
elf/Makefile | 5 ++
scripts/gen-sorted.awk | 6 ++
4 files changed, 187 insertions(+), 25 deletions(-)
--
2.43.0
More information about the Libc-alpha
mailing list