Skip to content

compile-many stage-2 workers serialize at ~200ms intervals — what's the shared lock? #341

Description

@zackees

Follow-up to #337. The framework-share seed lands the big perf win (3.7s/sketch → ~200ms/sketch on uno cold), but the stage-2 workers themselves finish in a strictly serial pattern despite `sketch_jobs=4` and 16 cores available locally.

Three consecutive cold-cache uno runs all show the same pattern:

Run s1 firmware mtime s2 +Δ s3 +Δ s4 +Δ
11:54 .588 +207ms +194ms +200ms
12:02 .806 +196ms +195ms +190ms
12:36 .216 +211ms +158ms +164ms

If all four workers actually ran in parallel for the same duration, their firmware.elf mtimes would land within a few ms of each other. Instead they consistently spread out at near-uniform 160–210ms intervals — workers are running in parallel for SOME of the time but blocking on something shared near the end.

Candidates I'd start poking at:

  • The shared zccache daemon (single sqlite WAL writer, even with WAL it serializes on commit)
  • avr-ld link step — single linker process per worker, possibly contending on a temp file or framework lib path
  • The fbuild perf-log mutex (probably not — even if it served all stage-2 workers, it's just a Mutex append)
  • NTFS filesystem-level locks on the shared framework cache dir (`~/.fbuild/prod/cache/platforms/arduino-ArduinoCore-avr/`)

The PERF_LOG isn't useful here because each stage-2 worker emits its own perf-log frame and they don't share a timeline. A quick way to triangulate would be to emit `tracing::info!` at known phase boundaries inside each worker (seed-start, seed-end, orchestrator-start, link-start, link-end) with a worker ID, then sort the resulting log lines on wall-clock to see which span is the long one. If link-end is what's spreading out across workers and link-start is bunched, it's contention in the linker phase; if seed-end is spread out, the seed is the bottleneck (unlikely given how small the hardlink set is).

Pragmatically, the current 200ms-per-sketch baseline is already 19× better than pre-#337, so this isn't urgent. But the same contention will scale linearly: 100 sketches × 200ms ≈ 20s of serialization that should be ~5s if the workers actually fanned out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions