From 57b685832375eb7443944cfdf78c40aff1ca327d Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Wed, 13 May 2026 14:04:54 -0700 Subject: [PATCH] perf(engine): bump worker count cap for high-core hosts (hf#732 PR 1/5) (#756) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary PR 1 of 5 in the hf#732 decomposition stack. Bumps `parallelCoordinator`'s worker-count caps so high-core hosts can actually surface their hardware to renders: - `ABSOLUTE_MAX_WORKERS`: 10 → 24 (explicit `--workers 16` now surfaces 16 DOM sessions instead of being silently clamped). - `DEFAULT_SAFE_MAX_WORKERS` constant → `defaultSafeMaxWorkers()` function returning `max(6, min(16, floor(cpus/8)))`. On <=32-core hosts: unchanged (still 6). On 64/96/128-core hosts: 8/12/16. No behavior change for typical hosts. Required prerequisite for the hybrid shader-transition path landed in PR 4. ## Test plan - [x] Existing 7 `parallelCoordinator` tests pass - [x] Engine typecheck clean - [x] oxlint clean ## Stack This is the base of the hf#732 decomposition stack: 1. **PR 1 (this)** — perf(engine): worker-count cap bump 2. PR 2 — feat(producer): add pngDecodeBlitWorkerPool 3. PR 3 — feat(producer): add shaderTransitionWorkerPool 4. PR 4 — perf(producer): hybrid layered/parallel path (the 2.22× speedup) 5. PR 5 — perf(producer): pipeline capture and shader-blend per-frame Replaces the closed hf#732. See that issue for the original investigation; the architectural mismatch with #733's `captureHdrStage` extraction made a clean rebase impossible. — Vai --- .../src/services/parallelCoordinator.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/engine/src/services/parallelCoordinator.ts b/packages/engine/src/services/parallelCoordinator.ts index bbee9a15e..4b21019bd 100644 --- a/packages/engine/src/services/parallelCoordinator.ts +++ b/packages/engine/src/services/parallelCoordinator.ts @@ -64,8 +64,23 @@ export interface WorkerSizingConfig extends Partial< const MEMORY_PER_WORKER_MB = 256; const MIN_WORKERS = 1; -const ABSOLUTE_MAX_WORKERS = 10; -const DEFAULT_SAFE_MAX_WORKERS = 6; +// Hard ceiling on explicit `--workers N` requests. Above this, the cost of +// CDP-protocol dispatch through Node's main event loop and OS scheduling +// noise overwhelms any further parallelism. Bumped from 10 → 24 in hf#732 +// follow-up so high-core hosts (32-96+ cores) can actually surface the +// hardware to renders that are CPU-bound on DOM capture. +const ABSOLUTE_MAX_WORKERS = 24; +// `auto` concurrency picks this many workers as the upper bound. Bumped +// from a hardcoded 6 → CPU-scaled value (floor(cpuCount/8), floor at 6, +// ceiling at 16) in hf#732 follow-up. Rationale: the prior fixed cap of 6 +// left ~90 cores idle on the validation host and forced users to pass +// `--workers N` to opt in. Now `auto` matches what a thoughtful operator +// would pick by hand. The /8 divisor leaves headroom for each Chrome +// worker's SwiftShader compositor + the shader-blend thread pool, both of +// which are themselves CPU-heavy. +function defaultSafeMaxWorkers(): number { + return Math.max(6, Math.min(16, Math.floor(cpus().length / 8))); +} const MIN_FRAMES_PER_WORKER = 30; export function calculateOptimalWorkers( @@ -79,7 +94,7 @@ export function calculateOptimalWorkers( if (concurrency !== "auto") { return Math.max(MIN_WORKERS, Math.min(ABSOLUTE_MAX_WORKERS, Math.floor(concurrency))); } - return DEFAULT_SAFE_MAX_WORKERS; + return defaultSafeMaxWorkers(); })(); const effectiveCoresPerWorker = config?.coresPerWorker ?? DEFAULT_CONFIG.coresPerWorker; const effectiveMinParallelFrames = config?.minParallelFrames ?? DEFAULT_CONFIG.minParallelFrames;