[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220213091619.GY614@gate.crashing.org>
Date: Sun, 13 Feb 2022 03:16:19 -0600
From: Segher Boessenkool <segher@...nel.crashing.org>
To: David Laight <David.Laight@...LAB.COM>
Cc: "'Christophe Leroy'" <christophe.leroy@...roup.eu>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>,
"linuxppc-dev@...ts.ozlabs.org" <linuxppc-dev@...ts.ozlabs.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] net: Remove branch in csum_shift()
On Sun, Feb 13, 2022 at 02:39:06AM +0000, David Laight wrote:
> From: Christophe Leroy
> > Sent: 11 February 2022 08:48
> >
> > Today's implementation of csum_shift() leads to branching based on
> > parity of 'offset'
> >
> > 000002f8 <csum_block_add>:
> > 2f8: 70 a5 00 01 andi. r5,r5,1
> > 2fc: 41 a2 00 08 beq 304 <csum_block_add+0xc>
> > 300: 54 84 c0 3e rotlwi r4,r4,24
> > 304: 7c 63 20 14 addc r3,r3,r4
> > 308: 7c 63 01 94 addze r3,r3
> > 30c: 4e 80 00 20 blr
> >
> > Use first bit of 'offset' directly as input of the rotation instead of
> > branching.
> >
> > 000002f8 <csum_block_add>:
> > 2f8: 54 a5 1f 38 rlwinm r5,r5,3,28,28
> > 2fc: 20 a5 00 20 subfic r5,r5,32
> > 300: 5c 84 28 3e rotlw r4,r4,r5
> > 304: 7c 63 20 14 addc r3,r3,r4
> > 308: 7c 63 01 94 addze r3,r3
> > 30c: 4e 80 00 20 blr
> >
> > And change to left shift instead of right shift to skip one more
> > instruction. This has no impact on the final sum.
> >
> > 000002f8 <csum_block_add>:
> > 2f8: 54 a5 1f 38 rlwinm r5,r5,3,28,28
> > 2fc: 5c 84 28 3e rotlw r4,r4,r5
> > 300: 7c 63 20 14 addc r3,r3,r4
> > 304: 7c 63 01 94 addze r3,r3
> > 308: 4e 80 00 20 blr
>
> That is ppc64.
That is 32-bit powerpc.
> What happens on x86-64?
>
> Trying to do the same in the x86 ipcsum code tended to make the code worse.
> (Although that test is for an odd length fragment and can just be removed.)
In an ideal world the compiler could choose the optimal code sequences
everywhere. But that won't ever happen, the search space is way too
big. So compilers just use heuristics, not exhaustive search like
superopt does. There is a middle way of course, something with directed
searches, and maybe in a few decades systems will be fast enough. Until
then we will very often see code that is 10% slower and 30% bigger than
necessary. A single insn more than needed isn't so bad :-)
Making things branch-free is very much worth it here though!
Segher
Powered by blists - more mailing lists