Re: [PATCH 0/2] arm64: csum: Add fused copy and Internet checksum
From: Demian Shulhan
Date: Tue Nov 03 2026 - 11:32:23 EST
> .L4:
> ldr x1, [x0, x4]
> adds x2, x2, x1
> cinc x3, x3, cs # adc $0,%rxx on x86
> adds x4, x4, 8
> bne .L4
Agreed, that is a nice loop for the sum-only case, one dependent op on
the sum chain and no builtin needed.
For the copy case I tried the same form on x86 (Zen 3, GCC 15, Clang
19-22, -O2) with a store added, against csum-copy_64.S, as posted it ran
at 0.85x of the asm with GCC and 0.73-0.76x with Clang (which rewrites
it into setb/adc), and ~0.8x unrolled 2x/4x - a bit slower than the
posted 4-accumulator loop (0.88-0.95x).
пн, 2 лист. 2026 р. о 17:14 David Laight <david.laight.linux@xxxxxxxxx> пише:
>
> On Mon, 2 Nov 2026 16:14:06 +0100
> Demian Shulhan <demyansh@xxxxxxxxx> wrote:
>
> > > The scalar path seems like generic C code and not restricted to arm64,
> > > curious how that performs against existing (e.g. x86) assembly
> > > optimized implementation.
> > Depends. I think __builtin_addcll() is needed to get roughly the same
> > performance as the asm version. In my tests GCC on arm64 turns it
> > into adds + cset instead of adcs like on x86.
> > But I will look at it, thanks!
>
> The C version I posted earlier has the loop:
> buf += count;
> count = -count;
> sum = carry = 0;
> do {
> val = *(u64 *)(buf + count);
> sum += val;
> carry += sum < val;
> } while ((count += 8));
>
> for aarch64 you get:
> .L4:
> ldr x1, [x0, x4]
> adds x2, x2, x1
> cinc x3, x3, cs # adc $0,%rxx on x86
> adds x4, x4, 8
> bne .L4
>
> I suspect that is close to optimal - especially for fast cpu with
> out of order execution.
>
> https://godbolt.org/z/eso79K7Wq
>
> David
>
> >
> > пн, 2 лист. 2026 р. о 12:44 saeed bishara <saeed.bishara.os@xxxxxxxxx> пише:
> > >
> > > On Sun, Nov 1, 2026 at 3:34 PM Demian Shulhan <demyansh@xxxxxxxxx> wrote:
> > > >
> > > > I would prefer to keep only the scalar version of the fused copy+csum.
> > > > It reads the data once instead of twice, and on real Armv9 hardware it
> > > > cuts end-to-end cycles/byte for bulk TCP over WireGuard by 3-12%
> > > > depending on the core (+6-8% throughput). It uses only general-purpose
> > > > registers, so there is no FPSIMD state to save and it is safe in any
> > > > context.
> > > >
> > > > If you are OK with the scalar path, I can send v2 with NEON dropped,
> > > > the scalar path only, and the KUnit fix for the x86 zero-length case
> > > > Jakub reported.
> > > >
> > > The scalar path seems like generic C code and not restricted to arm64,
> > > curious how that performs against existing (e.g. x86) assembly
> > > optimized implementation.
> > > saeed
>