From 7f392a6ff8b851e66bb387964680608b5852571d Mon Sep 17 00:00:00 2001 From: nomurak Date: Thu, 15 Oct 2026 15:40:33 -0700 Subject: [PATCH] multiload: use parallel accumulators in stream-sum The Makefile builds with -fno-unroll-loops. In clang this also disables loop-vectorizer interleaving, so the stream-sum reduction is vectorized with a single accumulator. Every iteration then waits on the previous vector add, which caps one thread at one 16-byte add per add latency (8 B/cycle on Neoverse N4, 16 B/cycle with 128-bit vpaddq on x86). Below DRAM sizes stream-sum was measuring this add chain, not the memory hierarchy. Request an interleave count of 4 on the stream-sum loop so clang keeps four independent accumulators. Explicit loop hints are honored even with -fno-unroll-loops. The pragma is guarded by __clang__ because GCC warns about unknown pragmas and the Makefile uses -Werror. GCC builds are unchanged. Single-thread stream-sum, MiB/s, median of 3 runs (pinned, -H): Neoverse N4 (3.6 GHz) 32k 27343 -> 91700 1m 27070 -> 74800 64m 27340 -> 52600 1g 24030 -> 25040 Xeon 6985P-C (GNR) 32k 62780 -> 124270 1m 63900 -> 93640 64m 28770 -> 28770 4g 21950 -> 21960 --- multiload.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/multiload.c b/multiload.c index c9494ab..b2d5a98 100644 --- a/multiload.c +++ b/multiload.c @@ -690,6 +690,13 @@ static void load_stream_sum(per_thread_t *t) { uint64_t active_ns = t->x.load_active_ns; do { CHECK_DUTY_CYCLE(interval_ns, active_ns) + // -fno-unroll-loops (Makefile CFLAGS) also disables clang vectorizer + // interleaving, leaving one accumulator and a loop-carried add chain. + // Request independent accumulators so the loop is load-bound. Guarded + // because GCC warns on unknown pragmas, and the Makefile uses -Werror. +#if defined(__clang__) +#pragma clang loop interleave_count(4) +#endif for (i = 0; i < N; ++i) { s += a[i]; }