Skip to main content

MINIMISE_BATCH_MIN_PROBLEMS

Constant MINIMISE_BATCH_MIN_PROBLEMS 

Source
pub const MINIMISE_BATCH_MIN_PROBLEMS: usize = 256;
Expand description

Problem count below which a ComputeBackend::CpuMulti request runs golden_section_batch on the calling thread instead.

§Measured crossover

Methodology. Measured 2026-08-13 on this workspace’s development machine, std::thread::available_parallelism() = 4, release build, --features parallel, rayon’s global pool, otherwise-idle machine. Batches of n independent problems (x - x0_i)^2 with the vertices x0_i spread over [-3, 3) so per-lane iteration counts differ, bracket [-5, 5], MinSettings::default, Sense::Minimise. Best of 7 samples per point, reported as wall clock for one whole batch. Produced by the #[ignore]d minimise_batch_crossover_benchmark test in minimise/tests.rs and transcribed from its printed output. The cheap objective is the two-flop parabola above; the costly objective adds a ln/exp/sqrt chain per evaluation, standing in for an equation-of-state flash. The (repeat) columns are the speed-ups from a second, independent run of the same benchmark, carried alongside rather than averaged away because the parallel column is far noisier than the serial one.

Problemscheap serialcheap multispeed-up(repeat)costly serialcostly multispeed-up(repeat)
162.24 us10.06 us0.22x0.24x13.87 us12.94 us1.07x0.41x
324.40 us29.98 us0.15x0.13x29.80 us44.04 us0.68x0.74x
648.77 us31.47 us0.28x0.34x63.53 us64.86 us0.98x1.24x
12817.96 us36.40 us0.49x0.86x140.68 us73.43 us1.92x1.42x
25655.42 us49.41 us1.12x1.17x290.00 us186.77 us1.55x2.91x
512148.21 us85.96 us1.72x3.00x613.95 us360.42 us1.70x2.94x
1 024370.80 us213.96 us1.73x2.81x1255.20 us675.41 us1.86x2.82x
4 0961542.64 us466.86 us3.30x3.23x5120.51 us1711.31 us2.99x2.86x
16 3846260.28 us1964.94 us3.19x2.09x20732.41 us10689.59 us1.94x2.69x
65 53628254.43 us8464.29 us3.34x1.55x84607.33 us32110.15 us2.63x2.03x

Result. 256 is the smallest size at which neither objective lost in either run — cheap 1.12x and 1.17x, costly 1.55x and 2.91x — and it is the value this constant takes. At 128 the cheap objective lost both runs (0.49x, 0.86x) while the costly one won both (1.92x, 1.42x), which is the expected shape: a more expensive objective crosses over earlier because there is more work per lane to amortise the same dispatch cost. The honest headline is therefore that the crossover depends on the caller’s objective, and this single number is set for the cheapest objective a caller is likely to pass, so that it is safe for both.

§Relationship to crate::compute::CPU_MULTI_MIN_WORK_ITEMS

That constant documents itself as an unmeasured placeholder and invites per-kernel overrides. This is that override for the batched golden section.

Interpretation. It lands on exactly the same value as crate::math::parallel::ROOT_BATCH_MIN_PROBLEMS (256), 16x below the crate-wide placeholder (4 096) and 512x below crate::fields::parallel::FIELD_PARALLEL_CROSSOVER (131 072). Two kernels agreeing is not a coincidence and is worth stating for whoever takes bead op-yvj.4.7: both do tens of iterations of arithmetic per lane against a handful of loaded bytes, so both are compute bound, where the field kernels do one or two flops per element loaded and are memory-bandwidth bound. The crossover tracks that distinction, not the algorithm.

§Limitations

One machine, four logical cores, one objective family, idle. Not measured on Android/Termux hardware and not on a many-core server. As with crate::math::parallel::ROOT_BATCH_MIN_PROBLEMS, the crossover moves with the caller’s objective cost, so a caller that knows its own objective is expensive is better off naming a ComputeBackend explicitly than trusting a single number.

§Units

A count of independent minimisation problems, dimensionless.