Adds benches/history_converge.rs with three workloads:
- 500 events / 100 competitors / 10 events per slice
- 2000 events / 200 competitors / 20 events per slice
- 5000 events / 50000 competitors / 5000 events per slice (gate workload)
Investigation found the original rayon path used a compute/apply split with
EventOutput heap allocation per event, causing 3-23x regression. Root cause:
per-event allocations caused heavy allocator contention across rayon threads.
Fixes:
- Replace EventOutput/two-phase approach with direct unsafe parallel write.
Events in a color group have disjoint agent index sets; concurrent writes
to SkillStore land on different Vec slots — no data race.
- Add RAYON_THRESHOLD=64: color groups below this size fall back to
sequential to avoid rayon overhead on small slices.
- Game internals: switch likelihoods/teams to SmallVec<[_;8]> to avoid
heap allocation for ≤8-team / ≤8-player-per-team games. Add type aliases
Teams<T,D> and Likelihoods to satisfy clippy::type_complexity.
- within_priors() and outputs() now return SmallVec; callers updated to
use ranked_with_arena_sv() directly (avoiding Vec→SmallVec conversion).
Sequential baseline (Apple M5 Pro, 2026-04-24):
500x100@10perslice: 4.72 ms
2000x200@20perslice: 23.17 ms
1v1-5000x50000@5000perslice: 13.89 ms
With --features rayon (RAYON_NUM_THREADS=5, P-cores on M5 Pro):
500x100@10perslice: 4.82 ms (1.0× — below threshold)
2000x200@20perslice: 23.09 ms (1.0× — below threshold)
1v1-5000x50000@5000perslice: 6.97 ms (2.0× speedup — GATE ACHIEVED)
T3 acceptance gate: >=2× speedup on at least one workload — ACHIEVED.
74 tests pass under both feature configs.
Part of T3.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
780 B
TOML
45 lines
780 B
TOML
[package]
|
|
name = "trueskill-tt"
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
|
|
[lib]
|
|
bench = false
|
|
|
|
[[bench]]
|
|
name = "batch"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "gaussian"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "history_converge"
|
|
harness = false
|
|
|
|
[dependencies]
|
|
approx = { version = "0.5.1", optional = true }
|
|
rayon = { version = "1", optional = true }
|
|
smallvec = "1"
|
|
|
|
[features]
|
|
approx = ["dep:approx"]
|
|
rayon = ["dep:rayon"]
|
|
|
|
[dev-dependencies]
|
|
criterion = "0.5"
|
|
plotters = { version = "0.3", default-features = false, features = ["svg_backend", "all_elements", "all_series"] }
|
|
plotters-backend = "0.3"
|
|
time = { version = "0.3", features = ["parsing"] }
|
|
trueskill-tt = { path = ".", features = ["approx"] }
|
|
|
|
[profile.release]
|
|
debug = true
|
|
|
|
[profile.bench]
|
|
debug = true
|
|
|
|
[profile.dev]
|
|
debug = true
|