pub const QUADRATURE_MIN_INTERVALS: usize = 32;Expand description
Interval count below which a ComputeBackend::CpuMulti request runs
quadrature_batch and adaptive_quadrature_batch on the calling thread
instead.
§Measured crossover
Methodology. Same machine, build and conditions as
ODE_ENSEMBLE_MIN_LANES (4 logical cores, release, --features parallel,
idle, best of 7 samples, three independent runs), measured 2026-08-13.
Batches of n independent integrals of exp(-a_i x) sin(b_i x) with
a_i in [0.1, 3) and b_i in [1, 30), over per-lane intervals inside
[0, 4], evaluated with QuadratureRule::GaussLegendre at
GaussOrder::G5 over 16 panels — 80 integrand evaluations per lane, about
1.4 us of serial work, a mid-cost rule. Produced by the #[ignore]d
quadrature_crossover_benchmark test in parallel/tests.rs and transcribed
from its printed output.
| Intervals | serial (run A) | speed-up A | speed-up B | speed-up C |
|---|---|---|---|---|
| 16 | 20.48 us | 1.36x | 1.16x | 0.51x |
| 32 | 40.96 us | 2.03x | 2.10x | 1.81x |
| 64 | 82.62 us | 1.95x | 2.47x | 2.62x |
| 128 | 170.22 us | 1.96x | 1.58x | 2.75x |
| 256 | 351.75 us | 3.15x | 3.47x | 3.29x |
| 1 024 | 1475.98 us | 3.61x | 3.79x | 3.74x |
| 4 096 | 6090.40 us | 3.89x | 3.75x | 3.97x |
| 16 384 | 24717.71 us | 3.89x | 3.75x | 3.90x |
Result. 32 is the smallest size at which the parallel path won in all three runs and kept winning at every larger size, and it is the value this constant takes. At 16 intervals it lost run C badly (0.51x).
Interpretation. Twice the ODE floor of 16, on lanes about 6x cheaper (1.4 us against 8.6 us). The two do not scale together, which is the honest reading of a measurement whose 16–128 region is dominated by run-to-run noise in both kernels; what both agree on is that a batch of a few hundred compute-dense lanes is comfortably worth threading and a batch of a handful is not. From 256 intervals upward the speed-up is a stable 3.1–4.0x on 4 logical cores.
This one floor is shared by both quadrature entry points, and it was
measured on the fixed-rule path only. adaptive_quadrature_batch costs
more per lane than any fixed rule a caller is likely to choose — the
verification lanes on that function needed 469 to 1 225 evaluations against
this rule’s 80 — so it crosses over earlier and inherits this floor as a
conservative assumption rather than a measurement. A caller whose fixed rule
is very cheap — say QuadratureRule::Trapezoid with one panel, two
evaluations — is well below what was measured and should pass a backend
explicitly.
§Contention
The same caveat as ODE_ENSEMBLE_MIN_LANES, and it bit harder here.
Three earlier runs taken while an unrelated rustc held ~234% CPU on the
same 4-core machine showed the parallel path losing at every size up to
64 and sitting at 0.98–1.02x — no speed-up at all — at 256 through 4 096,
where the idle machine gives 3.1–4.0x. A threshold measured on an idle
machine is optimistic for a process that shares its cores.
§Limitations
One machine, four logical cores, idle, one integrand family, one rule
(G5 over 16 panels). Not measured on Android/Termux. Not measured for the
adaptive path, for the trapezoid or Simpson rules, or for other Gauss orders.
§Units
A count of independent definite integrals, dimensionless.