Skip to content

Commit def6f54

Browse files
committed
fix(bench): gate oversubscribed C>=4 unbounded shapes behind a define
bench_unbounded was hanging in CI on the unbounded_sipmuc 1p4c shape: 4 consumers compete in a strict round-robin slot order (each consumer must take its turn before another can pop), and on a 4-vCPU runner one descheduled consumer blocks every other. The same starvation pattern hits every unbounded mupmuc shape with C>=4. Add `-d:BenchSkipOversubscribed` (set in PR CI bench.yml) that drops: - unbounded_sipmuc/mpmc_unbounded/1p4c - unbounded_mupmuc/mpmc_unbounded/{1p4c, 2p4c, 4p1c, 4p2c, 4p4c} mupsic shapes (multi-producer, single consumer) are kept regardless: the round-robin ordering exists on consumers only, so a single consumer cannot starve. mupsic 4p1c is also in tests/fixtures/pre-split-slugs.json and the deletion-safety guard would fail without it. The full grid still runs in `bench-comparison.yml` nightly cron / on workflow_dispatch where a beefier runner is available. PR CI now gets the meaningful subset (4 mupmuc shapes covering each P,C in {1,2}) that fits a 4-vCPU runner without hanging.
1 parent 8149901 commit def6f54

2 files changed

Lines changed: 27 additions & 13 deletions

File tree

.github/workflows/bench.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ jobs:
137137
-d:UnboundedMupmucMessageCount=50000 \
138138
-d:UnboundedMupmucRuns=2 \
139139
-d:BenchUnboundedWarmup=1 \
140+
-d:BenchSkipOversubscribed \
140141
benchmarks/nim/bench_unbounded.nim
141142
;;
142143
bench_latency)

benchmarks/nim/bench_unbounded.nim

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -441,35 +441,48 @@ proc runVariant(variant: string, em: var BMFEmitter) =
441441
UnboundedSipmucMessageCount)
442442
runUSipmucShape[2](em, UnboundedSipmucRuns, BenchUnboundedWarmup,
443443
UnboundedSipmucMessageCount)
444-
runUSipmucShape[4](em, UnboundedSipmucRuns, BenchUnboundedWarmup,
445-
UnboundedSipmucMessageCount)
444+
when not defined(BenchSkipOversubscribed):
445+
runUSipmucShape[4](em, UnboundedSipmucRuns, BenchUnboundedWarmup,
446+
UnboundedSipmucMessageCount)
446447
of "unbounded_mupsic":
448+
# mupsic shapes are kept under BenchSkipOversubscribed: a single
449+
# consumer cannot trigger the round-robin starvation that hangs
450+
# sipmuc/mupmuc with C >= 4, and `mpsc_unbounded/4p1c` is in the
451+
# pre-split deletion-safety fixture.
447452
runUMupsicShape[1](em, UnboundedMupsicRuns, BenchUnboundedWarmup,
448453
UnboundedMupsicMessageCount)
449454
runUMupsicShape[2](em, UnboundedMupsicRuns, BenchUnboundedWarmup,
450455
UnboundedMupsicMessageCount)
451456
runUMupsicShape[4](em, UnboundedMupsicRuns, BenchUnboundedWarmup,
452457
UnboundedMupsicMessageCount)
453458
of "unbounded_mupmuc":
454-
# {1,2,4} P x {1,2,4} C grid (9 shapes).
459+
# {1,2,4} P x {1,2,4} C grid (9 shapes). Shapes with P + C > 4
460+
# hang under 4-vCPU oversubscription: the round-robin consumer
461+
# ordering in unbounded_sipmuc/mupmuc forces strict per-shape
462+
# turn-taking, so a single descheduled consumer blocks every
463+
# other consumer. `-d:BenchSkipOversubscribed` (set in PR CI)
464+
# drops the offending shapes; the full grid still runs in
465+
# `bench-comparison.yml` nightly cron / on workflow_dispatch
466+
# where a beefier runner is available.
455467
runUMupmucShape[1, 1](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
456468
UnboundedMupmucMessageCount)
457469
runUMupmucShape[1, 2](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
458470
UnboundedMupmucMessageCount)
459-
runUMupmucShape[1, 4](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
460-
UnboundedMupmucMessageCount)
461471
runUMupmucShape[2, 1](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
462472
UnboundedMupmucMessageCount)
463473
runUMupmucShape[2, 2](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
464474
UnboundedMupmucMessageCount)
465-
runUMupmucShape[2, 4](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
466-
UnboundedMupmucMessageCount)
467-
runUMupmucShape[4, 1](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
468-
UnboundedMupmucMessageCount)
469-
runUMupmucShape[4, 2](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
470-
UnboundedMupmucMessageCount)
471-
runUMupmucShape[4, 4](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
472-
UnboundedMupmucMessageCount)
475+
when not defined(BenchSkipOversubscribed):
476+
runUMupmucShape[1, 4](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
477+
UnboundedMupmucMessageCount)
478+
runUMupmucShape[2, 4](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
479+
UnboundedMupmucMessageCount)
480+
runUMupmucShape[4, 1](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
481+
UnboundedMupmucMessageCount)
482+
runUMupmucShape[4, 2](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
483+
UnboundedMupmucMessageCount)
484+
runUMupmucShape[4, 4](em, UnboundedMupmucRuns, BenchUnboundedWarmup,
485+
UnboundedMupmucMessageCount)
473486
else:
474487
raise newException(ValueError, "unknown variant: " & variant)
475488

0 commit comments

Comments
 (0)