z constraint in powerpc inline assembly ?

Segher Boessenkool segher at kernel.crashing.org
Fri Jan 17 03:21:51 AEDT 2020


Hi!

On Thu, Jan 16, 2020 at 03:54:58PM +0000, David Laight wrote:
> if you are trying to 'loop carry' the 'carry flag' with 'add with carry'
> instructions you'll almost certainly need to write the loop in asm.
> Since the loop itself is simple, this probably doesn't matter.

Agreed.

> However a loop of 'add with carry' instructions may not be the
> fastest code by any means.
> Because the carry flag is needed for every 'adc' you can't do more
> that one adc per clock.
> This limits you to 8 bytes/clock on a 64bit system - even one
> that can schedule multiple memory reads and lots of instructions
> every clock.
> 
> I don't know ppc, but on x86 you don't even get 1 adc per clock
> until very recent (Haswell I think) cpus.
> Sandy/Ivy bridge will do so if you add to alternate registers.

The carry bit is renamed just fine on all modern Power cpus.  On Power9
there is an extra carry bit, precisely so you can do two interleaved
chains.  And you can run lots of these insns at once, every cycle.

On older cpus there were other limitations as well, but those have been
solved essentially.

> For earlier cpu it is actually difficult to beat the 4 bytes/clock
> you get by adding 32bit values to a 64bit register in C code.

Christophe uses a very primitive 32-bit cpu, not even superscalar.  A
loop doing adde is pretty much optimal, probably wants some unrolling
though.

> One possibility is to do a normal add then shift the carry
> into a separate register.
> After 64 words use 'popcnt' to sum the carry bits.
> With 2 accumulators (and carry shifts) you'd need to
> break the loop every 1024 bytes.
> This should beat 8 bytes/clock if you can exeute more than
> 1 memory read, one add and one shift each clock.

Do normal 64-bit adds, and in parallel also accumulate the values shifted
right by 32 bits.  You can add 4G of them this way, and restore the 96-bit
actual sum from these two accumulators, so that you can fold it to a proper
ones' complement sum after the loop.

But you can easily beat 8B/clock using vectors, or doing multiple addition
chains (interleaved) in parallel.  Not that it helps, your limiting factor
is the memory bandwidth anyway, if anything in the memory pipeline stalls
all your optimisations are for nothing.


Segher


More information about the Linuxppc-dev mailing list