Skip to content

linalg: gate par_chunks_mut/par_bin launches on two thresholds of work - #2986

Merged
kali merged 3 commits into
sonos:mainfrom
czoli1976:opt/threading-launch-gate
Oct 23, 2026
Merged

kali merged 3 commits into
sonos:mainfrom
czoli1976:opt/threading-launch-gate

Conversation

@czoli1976

@czoli1976 czoli1976 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

par_chunks_mut/par_bin launched on any tensor over the element threshold and always split into 4 * threads pieces — a tensor barely past the threshold was shredded into sub-threshold chunks and the launch cost more than it saved. A launch now needs at least two threshold-sized chunks of work. Once launched, every thread gets a chunk and the split grows with the work up to 4 * threads.

The first commit split by threshold count alone, which left cores idle on tensors two or three thresholds large: bench-vs-main flagged mobilenet_v2 pass_mt +7.2% on Cortex-A7, and M4 showed the same direction. The second commit restores the per-thread floor and lets depthwise conv size its split by its real work (output × kernel taps). The launch decision itself stays on the output size, so small depthwise planes keep running inline.

Benchmarks (Apple M4, 5-round interleaved A/B, medians vs main; 0 = all cores; measured before the rebase, on main 12e9af25)

model threads first commit this PR
tiny_rec 4 -13.3% -16.3%
tiny_rec 0 -9.9% -15.9%
mobilenet_v2 4 +0.7% -0.6%
mobilenet_v2 0 +10.3% -1.1%
mobilenet_v1 4 -0.1% +0.1%
mobilenet_v1 0 +3.6% -1.8%
inception_v3 4 -0.3% -1.1%
inception_v3 0 -6.3% -6.1%
medium_det 4 / 0 +0.4% / +3.6% +0.3% / -0.4%

Single-thread is unchanged (±0.4%, noise). MobileNet rows are parity within run noise; the first commit's MobileNet regression is gone. Tests cover the gate (one_threshold_stays_inline, two_thresholds_fill_every_thread, several_thresholds_split_once_per_thread). Cortex-A7 is for the bench bot to confirm.

🍍

@czoli1976
czoli1976 force-pushed the opt/threading-launch-gate branch from 5d7368a to 0b29317 Compare October 8, 2026 12:27
kali
kali previously approved these changes Oct 12, 2026
@kali
kali force-pushed the opt/threading-launch-gate branch from 0b29317 to 982cf20 Compare October 12, 2026 08:09
@kali kali self-assigned this Oct 12, 2026
@github-actions

Copy link
Copy Markdown

🔴 Bench vs main — 2 speed regression(s) · ⚠️ 8 secondary

Reference: 2026-10-12 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

Δ metric device main → PR
🔴 +7.6% en_tdnn_15M_nnef
evaltime · pulse_240ms
orangepi-rv2 67.5 ms/pulse
0.281 RTF → 72.6 ms/pulse
0.303 RTF
🔴 +7.2% mobilenet_v2_1
evaltime · pass_mt
cortex-a7 526 ms → 564 ms

Improvements

Δ metric device main → PR
🟢 -23.0% mobilenet_v2_1
evaltime · pass_mt
apple-m1-max 13.4 ms → 10.3 ms
🟢 -7.3% mobilenet_v2_1
evaltime · pass_mt
cortex-a53 188 ms → 175 ms
🟢 -6.8% inceptionv3
evaltime · pass_mt
apple-m1-max 43.8 ms → 40.8 ms
🟢 -5.8% mobilenet_v2_1
evaltime · pass
cortex-a53 403 ms → 379 ms
🟢 -5.8% mobilenet_v1_1
evaltime · pass
apple-m1-max 9.94 ms → 9.36 ms
⚠️ 8 secondary regression(s)
Δ metric device main → PR
⚠️ +25.6% nemotron_3_5_asr_streaming_0_6b_f32f32_preprocessor_1s
load · cuda
jetson-orin-nx 43 ms → 54 ms
⚠️ +21.2% speaker_id
RSS @ load · pulse8
cortex-a53 19.2 MB → 23.2 MB
⚠️ +9.6% en_tdnn_15M_nnef
load+optimize · pulse_240ms
beaglev-ahead 1.01 s → 1.1 s
⚠️ +9.6% en_tdnn_15M_nnef
load · pulse_240ms
beaglev-ahead 712 ms → 780 ms
⚠️ +7.5% en_tdnn_15M
load · pulse_120ms
beaglev-ahead 2.05 s → 2.21 s
⚠️ +7.5% en_tdnn_15M
load+optimize · pulse_120ms
beaglev-ahead 2.4 s → 2.58 s
⚠️ +7.3% mobilenet_v2_1
load · pass_mt
beaglev-ahead 1.34 s → 1.44 s
⚠️ +5.7% en_tdnn_lstm_bn_q7
RSS @ load · pulse_240ms
cortex-a53 24.9 MB → 26.4 MB

Bench numbers come from shared CI hardware and do produce false positives: a flagged
row is not on its own evidence of a real regression, and a clean report is not proof
there is none. Contributors do not need to chase what is reported here — leave the
reading of it to the maintainers, who will say if something needs action.

@czoli1976

Copy link
Copy Markdown
Contributor Author

@kali WDYT? does it need some work ?

@kali

kali commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

/ci bench

@kali

kali commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

when in doubt...

@github-actions

Copy link
Copy Markdown

⚠️ Bench vs main — no speed regressions · 2 secondary regression(s)

Reference: 2026-10-12 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

no inference-speed regressions

Improvements

Δ metric device main → PR
🟢 -23.1% mobilenet_v2_1
evaltime · pass_mt
apple-m1-max 13.4 ms → 10.3 ms
🟢 -7.5% mobilenet_v2_1
evaltime · pass_mt
cortex-a53 188 ms → 174 ms
🟢 -6.7% inceptionv3
evaltime · pass_mt
apple-m1-max 43.8 ms → 40.8 ms
🟢 -5.9% mobilenet_v1_1
evaltime · pass
apple-m1-max 9.94 ms → 9.35 ms
🟢 -5.9% mobilenet_v2_1
evaltime · pass
cortex-a53 403 ms → 379 ms
+1 more improvement(s)
Δ metric device main → PR
🟢 -5.6% en_tdnn_15M
evaltime · pulse_240ms
orangepi-rv2 71.1 ms/pulse
0.296 RTF → 67.1 ms/pulse
0.28 RTF
⚠️ 2 secondary regression(s)
Δ metric device main → PR
⚠️ +20.4% speaker_id
RSS @ load · pulse8
cortex-a53 19.2 MB → 23.1 MB
⚠️ +7.8% en_tdnn_lstm_bn_q7
RSS @ load · pulse_240ms
cortex-a55 24.7 MB → 26.7 MB

Bench numbers come from shared CI hardware and do produce false positives: a flagged
row is not on its own evidence of a real regression, and a clean report is not proof
there is none. Contributors do not need to chase what is reported here — leave the
reading of it to the maintainers, who will say if something needs action.

@github-actions

Copy link
Copy Markdown

❌ CI / cli: failure

  • ✅ build: success
  • ✅ test: success
  • ✅ llm-combos: success
  • ❌ llm: cancelled

View workflow run

@kali

kali commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

⚠️⚠️⚠️ Just rebased! ⚠️⚠️⚠️

@kali
kali force-pushed the opt/threading-launch-gate branch from 982cf20 to efc4104 Compare October 12, 2026 11:36
@czoli1976

Copy link
Copy Markdown
Contributor Author

@kali attempting a couple of improvements, commit to this or a follow up PR

@kali

kali commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

you can stack it up here.

@kali kali removed their assignment Oct 12, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Bench vs main — no speed regressions · 1 secondary regression(s)

Reference: 2026-10-12 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

no inference-speed regressions

Improvements

Δ metric device main → PR
🟢 -22.8% mobilenet_v2_1
evaltime · pass_mt
apple-m1-max 13.4 ms → 10.4 ms
🟢 -7.3% en_tdnn_15M
evaltime · pulse_240ms
orangepi-rv2 71.1 ms/pulse
0.296 RTF → 66 ms/pulse
0.275 RTF
🟢 -6.4% inceptionv3
evaltime · pass_mt
apple-m1-max 43.8 ms → 41 ms
🟢 -6.3% en_tdnn_8M
evaltime · pulse_120ms
apple-m1-max 1.19 ms/pulse
0.00993 RTF → 1.12 ms/pulse
0.0093 RTF
🟢 -5.9% mobilenet_v1_1
evaltime · pass
apple-m1-max 9.94 ms → 9.35 ms
+3 more improvement(s)
Δ metric device main → PR
🟢 -5.7% en_tdnn_8M
evaltime · pulse_180ms
cortex-a55 27.3 ms/pulse
0.152 RTF → 25.7 ms/pulse
0.143 RTF
🟢 -5.6% trunet
evaltime · pulse1_f16
cortex-a7 85 ms/pulse
8.5 RTF → 80.2 ms/pulse
8.02 RTF
🟢 -5.1% en_tdnn_15M
evaltime · pulse_120ms
apple-m1-max 2.34 ms/pulse
0.0195 RTF → 2.23 ms/pulse
0.0186 RTF
⚠️ 1 secondary regression(s)
Δ metric device main → PR
⚠️ +6.4% en_tdnn_lstm_bn_q7
RSS @ load · pulse_240ms
cortex-a55 24.7 MB → 26.3 MB

Bench numbers come from shared CI hardware and do produce false positives: a flagged
row is not on its own evidence of a real regression, and a clean report is not proof
there is none. Contributors do not need to chase what is reported here — leave the
reading of it to the maintainers, who will say if something needs action.

@czoli1976

Copy link
Copy Markdown
Contributor Author

@kali bench please

@kali
kali force-pushed the opt/threading-launch-gate branch from e054c73 to 58829fa Compare October 20, 2026 12:09
@github-actions

Copy link
Copy Markdown

🔴 Bench vs main — 1 speed regression(s) · ⚠️ 6 secondary

Reference: 2026-10-20 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

Δ metric device main → PR
🔴 +7.8% dfn3_enc
evaltime · s100
cortex-a55 63.3 ms → 68.3 ms

Improvements

Δ metric device main → PR
🟢 -6.0% inceptionv3
evaltime · pass_mt
apple-m1-max 44.7 ms → 42 ms
🟢 -5.1% dfn3_enc
evaltime · s100
cortex-a9 255 ms → 242 ms
⚠️ 6 secondary regression(s)
Δ metric device main → PR
⚠️ +15.9% mdl_en_2019_Q3_librispeech_onnx
RSS @ ready · 2600ms
i9-9900k 27.1 MB → 31.4 MB
⚠️ +11.1% nemotron_3_5_asr_streaming_0_6b_f32f32_joint_pass
RSS @ ready · cpu
i9-9900k 55.7 MB → 61.9 MB
⚠️ +7.8% en_tdnn_15M
load · pulse_240ms
beaglev-ahead 1.58 s → 1.71 s
⚠️ +7.6% en_tdnn_15M
load+optimize · pulse_240ms
beaglev-ahead 1.81 s → 1.95 s
⚠️ +6.2% voicecom_float
load+optimize · 2sec
cortex-a55 96 ms → 102 ms
⚠️ +5.8% voicecom_fake_quant
load+optimize · 2sec
cortex-a55 155 ms → 164 ms

Bench numbers come from shared CI hardware and do produce false positives: a flagged
row is not on its own evidence of a real regression, and a clean report is not proof
there is none. Contributors do not need to chase what is reported here — leave the
reading of it to the maintainers, who will say if something needs action.

@kali kali self-assigned this Oct 23, 2026
bench and others added 3 commits October 23, 2026 11:09
…ement threshold and always split the work into 4 * threads pieces, so a tensor barely over the threshold was shredded into chunks far smaller than the threshold and the launch cost more than the work saved. A launch now needs at least two threshold-sized chunks, and the split is bounded by the work present as well as by 4 * threads, so large tensors keep the old granularity for load balance.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… three thresholds large only that many chunks, so on a four-core part half the cores sat idle once the launch was already paid; MobileNet's late layers live in that band and regressed on Cortex-A7 (+7.2% pass_mt) and on M4 (+2.5-4.2%). A launch now gives every thread a chunk, growing with the work up to 4 * threads, in both par_chunks_mut and par_bin. Depthwise convolution still decides whether to launch on its output size, so small planes stay inline, but once a plane is large enough to launch it counts a whole kernel of multiply-adds per output point, so the split is sized by the work rather than the output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DepthWise::threading_work reads current_threading_element_threshold, but
tract-core only enables multithread-mm in its dev-dependencies, so the library
failed to build without it. The threshold is a plain atomic, so its static and
getter are now available whatever the features; the setter stays gated.
@kali

kali commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

⚠️⚠️⚠️ Just rebased! ⚠️⚠️⚠️

@kali
kali force-pushed the opt/threading-launch-gate branch from 58829fa to 6f31af3 Compare October 23, 2026 09:09
@github-actions

Copy link
Copy Markdown

🔴 Bench vs main — 1 speed regression(s) · ⚠️ 6 secondary

Reference: 2026-10-23 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

Δ metric device main → PR
🔴 +37.2% parakeet_tdt_600m_v3_f32f32_preprocessor_1s
evaltime · cpu
apple-m1-max 0.324 ms → 0.445 ms

Improvements

Δ metric device main → PR
🟢 -50.9% sd15_dummy_f32_vae_decoder_512px
evaltime · metal
apple-m1-max 672 ms → 330 ms
🟢 -50.0% sd15_dummy_f16_vae_decoder_512px
evaltime · metal
apple-m1-max 551 ms → 275 ms
🟢 -7.8% sd15_dummy_f16_unet_step_b2
evaltime · metal
apple-m1-max 400 ms → 369 ms
🟢 -7.5% sd15_dummy_f32_unet_step_b2
evaltime · metal
apple-m1-max 583 ms → 539 ms
🟢 -6.2% inceptionv3
evaltime · pass_mt
apple-m1-max 44 ms → 41.3 ms
⚠️ 6 secondary regression(s)
Δ metric device main → PR
⚠️ +12068.4% sd15_dummy_f16_vae_decoder_512px
heap @ ready · metal
apple-m1-max 101 MB → 12.3 GB
⚠️ +6094.6% sd15_dummy_f32_vae_decoder_512px
heap @ ready · metal
apple-m1-max 200 MB → 12.4 GB
⚠️ +245.5% sd15_dummy_f16_unet_step_b2
heap @ ready · metal
apple-m1-max 1.73 GB → 5.98 GB
⚠️ +123.2% sd15_dummy_f32_unet_step_b2
heap @ ready · metal
apple-m1-max 3.45 GB → 7.7 GB
⚠️ +5.9% en_tdnn_8M
load · pulse_180ms
cortex-a55 940 ms → 995 ms
⚠️ +5.6% en_tdnn_8M
load+optimize · pulse_180ms
cortex-a55 1.08 s → 1.15 s

Bench numbers come from shared CI hardware and do produce false positives: a flagged
row is not on its own evidence of a real regression, and a clean report is not proof
there is none. Contributors do not need to chase what is reported here — leave the
reading of it to the maintainers, who will say if something needs action.

@kali
kali merged commit 8882aa8 into sonos:main Oct 23, 2026
81 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants