Skip to content

perf: add opt-in precompiled headers for chain/protocol/wallet - #148

Closed
chiliec wants to merge 1 commit into
masterfrom
perf/precompiled-headers
Closed

perf: add opt-in precompiled headers for chain/protocol/wallet#148
chiliec wants to merge 1 commit into
masterfrom
perf/precompiled-headers

Conversation

@chiliec

@chiliec chiliec commented Aug 10, 2026

Copy link
Copy Markdown
Member

Adds precompiled-header (PCH) support for the three heaviest libraries, gated behind a new ENABLE_PCH option (default OFF). No source code touched.

Motivation

cmake_minimum_required is already 3.16, which has native target_precompile_headers, but nothing used it. Every translation unit in chain, protocol, and wallet re-parsed the same large template-heavy third-party headers from scratch. An include-frequency scan of each library's sources shows the cost concentrated in:

  • chain — Boost.MultiIndex containers (multi_index_container, ordered_index, hashed_index, composite_key) + FC serialization/reflection
  • protocol — FC reflection / static_variant + the operation type machinery
  • wallet — Boost.MultiIndex, Boost string/range algorithms, FC api/reflection

What this does

  • New libraries/{chain,protocol,wallet}/pch.hpp, each listing only stable third-party headers (Boost, FC, std). Project headers are deliberately excluded — a churning header in the PCH would force a full-library rebuild on every edit and defeat the purpose.
  • target_precompile_headers(<lib> PRIVATE pch.hpp) in each library, wrapped in if(ENABLE_PCH).
  • New root option(ENABLE_PCH ... OFF).

Safety

  • Default OFF — cannot affect existing builds, Docker images, or CI until a maintainer opts in.
  • ccache-aware: PCH and ccache conflict unless ccache is told not to hash the PCH. When ENABLE_PCH=ON, ccache is active, and CCACHE_SLOPPINESS lacks pch_defines,time_macros, CMake emits a warning (otherwise ccache silently disables its cache for PCH TUs — you'd lose the ccache win without gaining the PCH one).

Usage

cmake -S . -B build -DENABLE_PCH=ON
# if you use ccache:
export CCACHE_SLOPPINESS=pch_defines,time_macros

Validation

I don't have Boost dev libs or the submodules in my environment, so a full tree build wasn't possible. What I did verify with real cmake:

  • The ENABLE_PCH logic executes correctly: OFF prints a silent status line; ON prints status and the ccache warning only when CCACHE_SLOPPINESS is unset; ON + sloppiness is clean.
  • The target_precompile_headers wiring itself was proven end-to-end on a standalone CMake project mimicking the same shape — 24 TUs sharing one heavy header set. Single-threaded build: 16.84s → 5.73s (2.9×), with a real .pch artifact produced. (std headers stand in for Boost there; Boost.MultiIndex + FC reflection parse costs are at least as high, so this is a conservative proxy — not a measurement of this repo's actual numbers.)

Ask for the maintainer: run a real before/after on a build box —

# baseline
cmake -S . -B b_off && time cmake --build b_off -j$(nproc)
# with PCH
CCACHE_SLOPPINESS=pch_defines,time_macros cmake -S . -B b_on -DENABLE_PCH=ON && time cmake --build b_on -j$(nproc)

and confirm the win holds on this codebase before considering flipping the default.

Introduces target_precompile_headers for the three heaviest libraries, gated
behind a new ENABLE_PCH option (default OFF). CMake 3.16+ (already the minimum)
supports PCH natively; nothing used it before, so every translation unit
re-parsed the same large Boost.MultiIndex / FC reflection / std headers.

Each library gets a pch.hpp listing only *stable* third-party headers, chosen
from an include-frequency scan of that library's sources:
- chain    -> Boost.MultiIndex containers + FC serialization/reflection
- protocol -> FC reflection / static_variant + operation machinery
- wallet   -> Boost.MultiIndex, Boost string/range, FC api

Project headers are deliberately excluded: a churning header in the PCH would
force a full-library rebuild on every edit and defeat the purpose.

Default OFF so it cannot affect existing or CI builds until a maintainer opts
in and measures. ccache interaction is handled: when ENABLE_PCH is ON and
ccache is active but CCACHE_SLOPPINESS lacks pch_defines,time_macros, CMake
emits a warning (ccache otherwise disables its own cache for PCH TUs).

Validation (no Boost/submodules available in my env, so full tree build not run):
- Real cmake executes the ENABLE_PCH block correctly: OFF prints a silent
  status, ON prints status + the ccache warning only when sloppiness is unset.
- The target_precompile_headers wiring itself was proven on a standalone cmake
  project mimicking the same shape (24 TUs sharing a heavy header set): a
  single-threaded build went 16.84s -> 5.73s (2.9x) with a real .pch artifact
  produced. std headers stand in for Boost here; Boost.MultiIndex/FC parse
  costs are at least as high, so this is a conservative proxy.

Usage:
  cmake -S . -B build -DENABLE_PCH=ON
  # if using ccache:
  export CCACHE_SLOPPINESS=pch_defines,time_macros
On1x added a commit that referenced this pull request Aug 11, 2026
@On1x

On1x commented Aug 11, 2026

Copy link
Copy Markdown
Member

Folded into the pm branch (our mainnet-bound line, PR #124) to keep the HF14 work consistent and avoid master↔pm divergence. Full CI Docker build on pm is green. Closing here since the change now lives in pm; it'll reach master when pm merges. Thanks!

@On1x On1x closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants