Commit graph

4 commits

Author SHA1 Message Date
Admin
be21d627a0 box3d: opt-in broad-phase hybrid (parallel BVTT) — single-thread washer -19%, default off
WorldDef.enable_broad_phase_hybrid (default false; -bp=0/1 bench toggle):
an adaptive batch broad phase for high-churn scenes. When
move_count*4 > proxy_count, replaces the per-moved-proxy tree queries
(8k proxies x 3 root-descents on washer) with three BVTT self/cross
traversals (dynamic self + dynamic x static + dynamic x kinematic) that
share the upper-tree descent, plus an O(n) bottom-up refit instead of
the median rebuild. Both traversal and candidate-filter are parallelized
across the task system (per-worker buffers → merge → canonical sort by
(shape_a,shape_b,child) → deterministic contact creation).

Correctness: a #[cfg(debug_assertions)] SET-equality assertion (batch
candidate set == per-mover set) runs in every test and never fires — the
proof the BVTT finds identical contacts (the hash can't prove it since
creation order legitimately re-baselines). New test
determinism_broad_phase_hybrid_across_worker_counts. OFF hash 0x61E35C31
bit-identical; ON hash 0xBE99C5F7 identical across workers 1/2/4 +
external tasks. 180/186/180/180 tests, zero warnings, profile retrained.

Single-threaded washer -18.7% (17715 vs 21780, broad phase -51%) — beats
C (20661), within ~6% of Rapier (16844). DEFAULT OFF because it regresses
multi-threaded (washer w8 +52%): the batch materializes ~40-50k
candidates/step and serially merges+sorts them (a fundamental floor the
inline per-mover path avoids by filtering in the query callback), so at
w8 the parallel per-mover queries win. Cannot be worker-gated (would
break cross-worker determinism). Correct, deterministic, zero-cost when
off — an opt-in single-threaded accelerator for churn-heavy scenes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 02:48:47 +02:00
Admin
95eb8086fc box3d: tier-2 feature recycling (port extension) — default on, junkyard -8%
New middle tier between full manifold recycling and the full SAT, behind
WorldDef.enable_feature_recycling (default true; OFF path bit-identical,
hash 0x61E35C31 verified):

- Case A, separated-witness early-out: a previously-non-touching contact
  revalidates only the cached winning axis; still separating beyond the
  speculative distance means done in one test. Sound structurally: any
  cached axis is a valid separation witness (understates only, which
  falls through to the full SAT). Carried junkyard: 24k skips/step,
  full SATs 25.4k -> 4.5k per step.
- Case B, touching feature rebuild: re-clips the cached winning feature
  under explicit staleness bounds (SATCache::sat_pose at last full SAT,
  translation < 4x recycle distance, rotation < ~4.6 deg, forced refresh
  every 8 steps); degenerate rebuilds and touching<->separated
  transitions fall through same-step.

Probe-driven (junkyard: 89k full SATs/step on 105k pairs, 13k touching;
rapier maintains 3.4x fewer pairs): paired same-binary -fr=0/1 A/Bs show
junkyard -8% in every pairing (collide phase -15%), washer neutral to
-5%, pyramid/rain guards neutral, OFF costs nothing. Same-session
cross-engine junkyard: rapier's -8% lead closes to ~-3%.

pgo.sh now trains BOTH modes (single-mode training starved the remaining
full-SAT path); checked-in profile retrained dual-mode. SATCache pose
serialized in snapshots. feature_recycled_contact_count in Counters.
README: port-extension subsection, soundness argument, updated notes.
Also: rapier bench --probe mode from the workload-probe session.

179/185/179/179 tests green with the tier ON, zero warnings,
determinism suite passes across runs/workers/task systems.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 23:40:08 +02:00
Admin
66b42fc9dd box3d: multithreading — scheduler, parallel_for, atomic solver stages
Port of the C threading design: worker threads with a fixed task ring and
help-while-waiting finish (scheduler.rs), atomic block-claiming parallel_for,
and the solver's stage machinery (per-block syncIndex CAS, sync-bits stage
advancement, mainClaimed race). Parallel narrow phase, broad-phase pairs,
sensors, finalize. Shared access goes through documented disjointness
primitives (sync.rs: SyncPtr/SyncSlice/AtomicIndex); worker_count 1 keeps the
serial path bit-identically. Results are bit-identical at any worker count
(determinism hash 0x7A796F4F asserted at 1/2/4 workers). 8 workers: 3.4-5.7x
over serial on heavy scenes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
60ec705ab2 box3d: SIMD (SSE2/NEON), double-precision large world, snapshots, benchmarks
- contact solver wide ops + V32 now have real SSE2 and NEON paths selected
  by target arch; scalar fallback behind the disable-simd feature. All three
  paths are bit-identical (cross-arch determinism verified: same ragdoll
  hash on NEON, SSE2 under Rosetta, and scalar).
- double-precision feature (C BOX3D_DOUBLE_PRECISION): f64 world positions
  with the exact C boundary-function semantics; enables the far-from-origin
  test halves (157 tests in DP mode, 151 default).
- world snapshots: recording substrate subset (buffer/writers/geometry
  registry/readers) + world_snapshot.c port; bit-identical continuation
  after restore, corrupt-image rejection.
- examples/benchmark.rs: all 10 C benchmark scenarios; serial Rust runs
  1.05-1.55x slower than C -O2 at one worker (geomean ~1.3x with fat LTO).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00