docs: record the rayon opt-in deviation in spec section 6
Issue #5 asked for a decision, not an implementation: either flip rayon to default-on, or record why the spec was deviated from and close. Opt-in stands. The measured speedups are 1.0x realistic / 1.3x pathological (#4), so default-on would cost every downstream user a thread pool and a dependency for approximately nothing. The condition the decision was waiting on cannot be met: #5 was blocked on re-measuring after cross-slice dirty-bit skipping landed, and #4 was closed by removing the inert slices_skipped field rather than by implementing it. There is no forthcoming measurement to wait for. Also corrects the spec's own reasoning. It cited an unsafe concurrent write through SkillStore as a cost of going default-on; the crate is forbid(unsafe_code) and the compute/apply split avoids that entirely. The case for opt-in is the measurements, not a safety argument. Closes #5 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ
This commit is contained in:
@@ -500,6 +500,26 @@ All public traits (`Time`, `Drift`, `Observer`, `Factor`, `Schedule`) require `S
|
||||
|
||||
`rayon` as default-on feature; with `default-features = false`, parallel paths fall back to sequential iterators behind `cfg(feature = "rayon")`.
|
||||
|
||||
> **Not implemented. Deliberate deviation, decided 2026-09-08 (issue #5).**
|
||||
>
|
||||
> `rayon` ships **opt-in**: `Cargo.toml` has no `default = [...]` key. The
|
||||
> measured speedups are 1.0x on realistic workloads and 1.3x on a pathological
|
||||
> one (issue #4), because typical slices hold too few events to amortize
|
||||
> rayon's task-spawn overhead. Default-on would hand every downstream user a
|
||||
> thread pool and a dependency for approximately no gain.
|
||||
>
|
||||
> This section made the trade conditional on cross-slice dirty-bit skipping
|
||||
> landing and changing the parallel story. It did not land: #4 was closed on
|
||||
> 2026-08-27 by removing the inert `ConvergenceReport::slices_skipped` field
|
||||
> rather than by implementing the mechanism, so the re-measurement this was
|
||||
> waiting on will not arrive.
|
||||
>
|
||||
> The "Trade-offs" note below also cited an `unsafe` concurrent-write path
|
||||
> through `SkillStore` as a cost of default-on. That cost does not exist: the
|
||||
> crate is `#![forbid(unsafe_code)]`, and the compute/apply split on the
|
||||
> internal `Event` is what lets a color group run in parallel without it. The
|
||||
> case for opt-in rests on the measurements alone.
|
||||
|
||||
### Expected speedup ballpark
|
||||
|
||||
For 1000 players, 60 events/slice × 1000 slices, 30 convergence iterations:
|
||||
@@ -521,7 +541,7 @@ These are pre-implementation estimates. Each tier validates with criterion.
|
||||
- Color-group parallelism requires up-front graph coloring at ingestion. Cost: linear in events, run once per `add_events`. Cheap.
|
||||
- Default = asynchronous EP (preserves current semantics). Synchronous opt-in only.
|
||||
- Cross-slice sweep stays sequential; no speculative parallel sweeps.
|
||||
- Rayon default-on but feature-gated.
|
||||
- Rayon default-on but feature-gated. **Superseded — shipped opt-in; see the deviation note in Section 6.**
|
||||
|
||||
### Open question
|
||||
|
||||
|
||||
Reference in New Issue
Block a user