Skip to main content

QUADRATURE_MIN_INTERVALS

Constant QUADRATURE_MIN_INTERVALS 

Source
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.

Intervalsserial (run A)speed-up Aspeed-up Bspeed-up C
1620.48 us1.36x1.16x0.51x
3240.96 us2.03x2.10x1.81x
6482.62 us1.95x2.47x2.62x
128170.22 us1.96x1.58x2.75x
256351.75 us3.15x3.47x3.29x
1 0241475.98 us3.61x3.79x3.74x
4 0966090.40 us3.89x3.75x3.97x
16 38424717.71 us3.89x3.75x3.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.