]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Filter timing outliers with IQR in batch-timing library
authorPuranjay Mohan <puranjay@kernel.org>
Wed, 20 May 2026 13:33:32 +0000 (06:33 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 20 May 2026 16:25:47 +0000 (09:25 -0700)
System noise (timer interrupts, scheduling) can inflate the reported
stddev.  tcp-v4-syn showed stddev 37.86 ns without filtering vs
0.16 ns with filtering on the same run data.

Filter samples outside [Q1 - 1.5*IQR, Q3 + 1.5*IQR] before computing
statistics.  Scenarios with genuinely wide distributions have large IQR
so the fences stay wide and the filter has minimal effect.

Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/r/20260520133338.3392667-4-puranjay@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/benchs/bench_bpf_timing.c

index 75a39da6965526ed6c8529d25db9690cac7476c0..e02ad324f7bcf1451038fe1bc219953270deddd2 100644 (file)
@@ -65,6 +65,31 @@ static int collect_samples(struct bpf_bench_timing *t,
        return total;
 }
 
+static int filter_outliers_iqr(double *sorted, int n)
+{
+       double q1, q3, iqr, lo, hi;
+       int start = 0, end = n;
+
+       if (n < 8)
+               return n;
+
+       q1 = sorted[n / 4];
+       q3 = sorted[3 * n / 4];
+       iqr = q3 - q1;
+       lo = q1 - 1.5 * iqr;
+       hi = q3 + 1.5 * iqr;
+
+       while (start < end && sorted[start] < lo)
+               start++;
+       while (end > start && sorted[end - 1] > hi)
+               end--;
+
+       if (start > 0)
+               memmove(sorted, sorted + start, (end - start) * sizeof(double));
+
+       return end - start;
+}
+
 static void compute_stats(const double *sorted, int n,
                          struct timing_stats *s)
 {
@@ -150,6 +175,7 @@ void bpf_bench_timing_report(struct bpf_bench_timing *t, const char *name, const
                return;
        }
 
+       total = filter_outliers_iqr(all, total);
        compute_stats(all, total, &s);
 
        if (t->machine_readable) {