Skip to content

Interner front caches and sharded capacity fix - #106

Open
xmakro wants to merge 2 commits into
base-interner-969b803from
perf/interner-front-cache
Open

Interner front caches and sharded capacity fix#106
xmakro wants to merge 2 commits into
base-interner-969b803from
perf/interner-front-cache

Conversation

@xmakro

@xmakro xmakro commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Two changes to the type interners, aimed at the interning + hashbrown cost that profiling shows at ~5-6% of check builds, and at the parallel-mode memory footprint.

Commit 1: ShardedHashMap::with_capacity now means total capacity across shards. Previously every one of the 32 shards received the full requested capacity, so with -Zthreads > 1 each CtxtInterners table allocated 32x its intended size. The dep-graph call site already divided by shards() to compensate; that division moved inside. Serial behavior is bit-identical (single shard, divide by 1). Measured: ~41-43 MB max-rss reduction per rustc process at -Zthreads=8 (syn -15%, serde -12%, regex-automata -11%), instructions:u neutral (+0.00% mean over 32 cells).

Commit 2: per-worker front caches for the four hottest interners (types, predicates, generic-arg lists, type lists). Interning is dominated by hits on recently-interned values, but each hit probes a large, mostly cache-cold hash table under a shard lock. A 4096-entry direct-mapped array per worker (via WorkerLocal, like the arena) is checked first using the already-computed Fx hash; hits skip the lock and the probe, misses fall through to the shared interner and fill the slot. The RefCell borrow is held across the fallback so unexpected reentrance panics rather than corrupting the cache.

Measurements (stage2 ThinLTO + jemalloc, Check profile):

  • instructions:u, 32 benchmark cells (Full / incr-full / incr-unchanged over syn, serde, regex-automata, cranelift-codegen, typenum, bitmaps, diesel, hyper incl. new-solver variants): mean -1.43%, median -1.21%, no regressions. Largest: diesel-new-solver -3.8%, typenum-new-solver -3.5%, diesel -2.8%, serde -2.5%, hyper -1.8%, syn -1.4%. Trait-solver-heavy crates benefit most, matching predicate interning being the hottest single interner in profiles.
  • Paired interleaved wall time (7 alternating iterations per cell): median ~-3.5% across crates at both -Zthreads=1 and =8; regex-automata -8.7%. Wall on this machine is noisy (±3-5% per cell); the instruction counts are the authoritative serial metric.
  • cachegrind on syn check: Ir -1.43% (matching the hardware counters), D1 read misses -1.0%, data writes -1.8%.

FRONT_CACHE_BITS = 12 is untuned; the const and clauses interners are not covered yet and are candidates for a follow-up.

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.

1 participant