From fb4021b7de76ceed0063be3e776278f11029deef Mon Sep 17 00:00:00 2001 From: Max Buckley Date: Tue, 21 Jul 2026 23:58:12 +0200 Subject: [PATCH] perf(pdlp): widen small-problem termination-check stride (10 -> 25) conditional_major() controls how often PDLP runs a full termination/convergence evaluation in the sub-1000-iteration regime. That evaluation is an un-graphed ~12-15 kernel eager launch chain plus a blocking cudaStreamSynchronize, which is disproportionately expensive next to a single graphed PDHG step on small edge/MPC-sized LPs. At the default stride of 10, a controller-sized LP that converges in a few hundred iterations pays 20-40 of these evaluations. Widen the small-problem stride to 25, trading a few extra cheap graphed PDHG steps of convergence-detection latency for roughly 2.5x fewer expensive evaluations. Larger regimes keep the x10 scaling. Not bit-identical: convergence is detected up to stride-1 iterations later, so a few extra PDHG steps may run; the reported optimum and termination status are unchanged. The constant should be re-tuned against measured net solve time on the mpc_H*/assign_* suite (bench_lp_robotics). Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Max Buckley --- cpp/src/pdlp/utils.cuh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cpp/src/pdlp/utils.cuh b/cpp/src/pdlp/utils.cuh index adc1432b39..04f2558641 100644 --- a/cpp/src/pdlp/utils.cuh +++ b/cpp/src/pdlp/utils.cuh @@ -66,7 +66,19 @@ struct max_abs_value { template i_t conditional_major(uint64_t total_pdlp_iterations) { - uint64_t step = 10; + // `step` is how often (in PDHG iterations) the sub-1000-iteration regime runs a full + // termination/convergence evaluation. That evaluation is an un-graphed chain of ~12-15 + // eager kernel launches plus one blocking cudaStreamSynchronize (termination_strategy.cu), + // which is expensive relative to a single graphed PDHG step on small edge/MPC-sized LPs. + // At step=10 a controller-sized LP that converges in a few hundred iterations pays ~20-40 + // such evaluations. Widening the stride trades a handful of extra (cheap, graphed) PDHG + // steps of convergence-detection latency for far fewer expensive evaluations — a net win in + // the small-problem regime that dominates on-robot use. Larger regimes keep the x10 scaling. + // + // NOT bit-identical: convergence is detected up to `step-1` iterations later, so a few extra + // PDHG steps may run; the reported optimum/termination status are unchanged. Benchmark on the + // mpc_H*/assign_* suite and re-tune this constant against measured net solve time. + uint64_t step = 25; uint64_t threshold = 1000; [[maybe_unused]] uint64_t iteration = 0;