[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <dc1f54f90642401ca6135c75e399c06d@AcuMS.aculab.com>
Date: Sun, 28 Jan 2024 12:35:53 +0000
From: David Laight <David.Laight@...LAB.COM>
To: 'Jisheng Zhang' <jszhang@...nel.org>, Paul Walmsley
<paul.walmsley@...ive.com>, Palmer Dabbelt <palmer@...belt.com>, Albert Ou
<aou@...s.berkeley.edu>
CC: "linux-riscv@...ts.infradead.org" <linux-riscv@...ts.infradead.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>, Matteo Croce
<mcroce@...rosoft.com>, kernel test robot <lkp@...el.com>
Subject: RE: [PATCH 1/3] riscv: optimized memcpy
From: Jisheng Zhang
> Sent: 28 January 2024 11:10
>
> From: Matteo Croce <mcroce@...rosoft.com>
>
> Write a C version of memcpy() which uses the biggest data size allowed,
> without generating unaligned accesses.
>
> The procedure is made of three steps:
> First copy data one byte at time until the destination buffer is aligned
> to a long boundary.
> Then copy the data one long at time shifting the current and the next u8
> to compose a long at every cycle.
> Finally, copy the remainder one byte at time.
>
> On a BeagleV, the TCP RX throughput increased by 45%:
..
> +static void __memcpy_aligned(unsigned long *dest, const unsigned long *src, size_t count)
> +{
You should be able to remove an instruction from the loop by using:
const unsigned long *src_lim = src + count;
for (; src < src_lim; ) {
> + for (; count > 0; count -= BYTES_LONG * 8) {
> + register unsigned long d0, d1, d2, d3, d4, d5, d6, d7;
register is completely ignored and pointless.
(More annoyingly auto is also ignored.)
> + d0 = src[0];
> + d1 = src[1];
> + d2 = src[2];
> + d3 = src[3];
> + d4 = src[4];
> + d5 = src[5];
> + d6 = src[6];
> + d7 = src[7];
> + dest[0] = d0;
> + dest[1] = d1;
> + dest[2] = d2;
> + dest[3] = d3;
> + dest[4] = d4;
> + dest[5] = d5;
> + dest[6] = d6;
> + dest[7] = d7;
> + dest += 8;
> + src += 8;
There two lines belong in the for (...) statement.
> + }
> +}
If you __always_inline the function you can pass &src and &dest
and use the updated pointers following the loop.
I don't believe that risc-v supports 'reg+reg+(imm5<<3)' addressing
(although there is probably space in the instruction for it.
Actually 'reg+reg' addressing could be supported for loads but
not stores - since the latter would require 3 registers be read.
We use the Nios-II cpu in some fpgas. Intel are removing support
in favour of Risc-V - we are thinking of re-implementing Nios-II
ourselves!
I don't think they understand what the cpu get used for!
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
Powered by blists - more mailing lists