Skip to content

Build: instrument the build (CMake Instrumentation API), then revisit the -j6 parallelism cap with data #759

Description

@drsnuggles8

Problem

We cap every build at 6 jobs (--parallel 6 / CMAKE_BUILD_PARALLEL_LEVEL=6, plus OLO_LINK_JOBS=2 for the Ninja link pool) because the dev box is 16c/31GB, also hosts three CI runners for another repo, and has been OOM-killed once by a full-width build.

That cap is a memory decision made without memory data. We don't know:

  • whether the link pool or compilation is the actual serialisation point,
  • what peak RSS at -j6 really is, and therefore whether there's headroom,
  • which targets dominate wall-clock, and
  • whether targets are blocked waiting on dependency edges rather than on CPU.

Proposal

Bill Hoffman's CMake's Recent Evolution (C++Now 2026, Kitware) covers the Instrumentation API, which answers exactly these. It emits one JSON snippet per configure / generate / compile / link / install / test step carrying timeStart, duration, role, language, outputSizes, and — the interesting part here — beforeCPULoadAverage / afterCPULoadAverage and beforeHostMemoryUsed / afterHostMemoryUsed. Snippets collate into an index and render as a Google Trace Event file.

Work:

  1. Enable instrumentation for one clean build of build/ (msvc) and read the trace.
  2. Answer the two questions above with numbers — is the link pool the long pole, and is there memory headroom at -j6? Record the answer in this issue so the cap stops being folklore. If the data says the cap can move, move it; if it says the cap is right, that's equally valuable and this issue closes as "measured, no change".
  3. Try OPTIMIZE_DEPENDENCIES ON. The talk flags it as the fix for the "compilation blocked by dependent targets" shape, and it drops unnecessary dependency edges from static and object libraries. OloEngine is a static lib with four dependents (OloEditor, OloRuntime, OloServer, OloEngine-Tests), which is precisely the configuration it targets. Re-trace and compare.
  4. Optionally check INSTALL_PARALLEL — likely irrelevant since we don't install, noted only so it isn't re-discovered later.

Acceptance

  • A committed trace-derived summary (in this issue, not a tracked file) giving: total configure/generate/build time, the top 5 targets by compile+link time, peak host memory at -j6, and whether the link pool is the constraint.
  • An explicit decision on the parallelism cap, with the number behind it.
  • OPTIMIZE_DEPENDENCIES either adopted with a measured delta, or rejected with one.

Notes / risks

  • Instrumentation is still marked experimental in the CMake 4.x line — hence confidence 0.8 rather than 1.0. Local toolchain is CMake 4.2.
  • Support may differ between the Visual Studio generator (build/) and Ninja (build-clang/). If it only works cleanly under Ninja, the clangcl tree is still a valid subject for the dependency-edge question, but the memory numbers should come from the tree we actually build most.
  • Do not run this concurrently with a build-clang/ build — see Build: build-graph-integrate the OloHeaderTool codegen (add_custom_command + DEPFILE + CODEGEN) #758 and the CLAUDE.md cross-tree warning.
  • This is deliberately a measurement issue. Scope creep into "and then optimise the build" should become a separate issue with the trace as evidence.

Source: C++Now 2026 review.

Score

capability: 3
craft: 1
stability: 3
decay: 1
effort: 2
confidence: 0.8
learning: 5
fun: 3
kano: performance
blocked_by: []
blocks: []

Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort, derived by the picker.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance / data-oriented optimizationtoolingMCP / dev-tooling / codegen — exempt from feature freeze

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions