[PATCH] Power7 optimizations for strncpy and stpncpy.
R Vidya
vidya@linux.vnet.ibm.com
Fri May 2 18:15:00 GMT 2014
Hi , Comments incorporated and patch sent.
On Friday 11 April 2014 07:33 PM, Adhemerval Zanella wrote:
> Hi Vidya,
>
> Some comments:
>
>
> On 10-04-2014 10:40, vidya@linux.vnet.ibm.com wrote:
>> From: Vidya Ranganathan <vidya@linux.vnet.ibm.com>
>>
>> The optimization is achieved by following techniques:
>> > data alignment [gain from aligned memory access on read/write]
>> > prefetch data [gain from cache misses by anticipating load]
>> > POWER7 gains performance with loop unrolling/unwinding
>> [gain by reduction of branch penalty].
>>
>> ChangeLog:
>> 2014-03-27 Vidya Ranganathan <vidya@linux.vnet.ibm.com>
>>
>> * sysdeps/powerpc/powerpc64/power7/strncpy.S: New file: Optimization.
>> * sysdeps/powerpc/powerpc64/multiarch/strncpy.c: New file:
>> multiarch strncpy for PPC64.
>> * sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c: New file
>> * sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S: New file
>> * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strpcpy, stpncpy
>> multiarch optimizations
> Missing period.
>
>
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
>> new file mode 100644
>> index 0000000..0766fa8
>> --- /dev/null
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
>> @@ -0,0 +1,35 @@
>> +/* Multiple versions of strncpy.
>> + Copyright (C) 2014 Free Software Foundation, Inc.
>> + This file is part of the GNU C Library.
>> +
>> + The GNU C Library is free software; you can redistribute it and/or
>> + modify it under the terms of the GNU Lesser General Public
>> + License as published by the Free Software Foundation; either
>> + version 2.1 of the License, or (at your option) any later version.
>> +
>> + The GNU C Library is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + Lesser General Public License for more details.
>> +
>> + You should have received a copy of the GNU Lesser General Public
>> + License along with the GNU C Library; if not, see
>> + <http://www.gnu.org/licenses/ >. */
>> +
>> +/* Define multiple versions only for definition in libc. */
>> +#ifndef NOT_IN_libc
>> +# include <string.h>
>> +# include <shlib-compat.h>
>> +# include "init-arch.h"
>> +
>> +extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
>> +extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
>> +
>> +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>> + ifunc symbol properly. */
>> +libc_ifunc (strncpy,
>> + (hwcap & PPC_FEATURE_HAS_VSX)
>> + ? __strncpy_power7
>> + : __strncpy_ppc);
>> +
>> +#endif
> The indentation is strange, please follow the other files.
>
>> diff --git a/sysdeps/powerpc/powerpc64/power7/strncpy.S b/sysdeps/powerpc/powerpc64/power7/strncpy.S
>> new file mode 100644
>> index 0000000..31fecc6
>> --- /dev/null
>> +++ b/sysdeps/powerpc/powerpc64/power7/strncpy.S
>> @@ -0,0 +1,468 @@
>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
>> + This file is part of the GNU C Library.
>> +
>> + The GNU C Library is free software; you can redistribute it and/or
>> + modify it under the terms of the GNU Lesser General Public
>> + License as published by the Free Software Foundation; either
>> + version 2.1 of the License, or (at your option) any later version.
>> +
>> + The GNU C Library is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + Lesser General Public License for more details.
>> +
>> + You should have received a copy of the GNU Lesser General Public
>> + License along with the GNU C Library; if not, see
>> + <http://www.gnu.org/licenses/>. */
>> +
>> +#include <sysdep.h>
>> +
>> +/* Implements the functions
>> +
>> + char * [r3] strncpy (char *dst [r3], const char *src [r4], size_t n [r5])
>> +
>> + AND
>> +
>> + char * [r3] stpncpy (char *dst [r3], const char *src [r4], size_t n [r5])
>> +
>> + The algorithm is as follows:
>> + > if src and dest are 8 byte aligned, perform double word copy
>> + else
>> + > if src and dest are 4 byte aligned, perform word copy
>> + else
>> + > copy byte by byte on unaligned addresses.
>> +
>> + The aligned comparison are made using cmpb instructions. */
>> +
>> +/* The focus on optimization for performance improvements are as follows:
>> + 1. data alignment [gain from aligned memory access on read/write]
>> + 2. prefetch data [gain from cache misses by anticipating load]
>> + 3. POWER7 gains performance with loop unrolling/unwinding
>> + [gain by reduction of branch penalty]. */
>> +
>> +#ifdef USE_AS_STPNCPY
>> +# define FUNC_NAME __stpncpy
>> +#else
>> +# define FUNC_NAME strncpy
>> +#endif
>> +
>> +#define FRAMESIZE (FRAME_MIN_SIZE+32)
>> +
>> + .machine power7
>> +EALIGN(FUNC_NAME, 4, 0)
>> + CALL_MCOUNT 3
>> +
>> + dcbt 0, r3 /* CPU pre-fetch dst to avoid cache miss */
>> + dcbt 0, r4 /* CPU pre-fetch src to avoid cache miss */
>> +
>> + mflr r0 /* load link register LR to r0 */
>> + or r9, r3, r4 /* to verify source and destination */
>> + rldicl. r10, r9, 0, 61 /* is doubleWord aligned ..? */
>> +
>> + std r31, -8(r1) /* save callers register , r31 */
>> + std r30, -16(r1) /* save callers register , r30 */
>> + std r15, -24(r1) /* save callers register , r15 */
>> + std r0, 16(r1) /* store the link register */
>> + stdu r1, -FRAMESIZE(r1) /* create the stack frame */
>> +
>> + mr r15, r3 /* save r3 into r15 as retcode for strncpy */
>> + mr r31, r3 /* save r3 into r31 for use */
>> + beq cr0,L(dwordAligned)
>> + rldicl. r10, r9, 0, 62 /* is word aligned .. ? */
>> + bne cr0,L(byte_by_byte)
> Checking the patch performance I noted the aligned load/store using words is not
> showing much difference in word aligned source/destiny. I tested removing the
> code and the shorted code path helped latency a little for shorter strings. I
> think it is better to use doubleword logic.
>
>
>> +
>> +L(zeroFill):
>> + cmpdi cr7, r10, 0 /* compare if length is zero */
>> + beq cr7,L(hop2Return)
>> + mr r3, r31 /* fill buffer with zero */
>> + li r4, 0 /* buffer size to fill zero with */
>> + mr r5, r10 /* fill buffer target */
>> + bl memset /* fill with zeroes */
>> + nop /* trigger CPU activity */
> This will generate a PLT relocation, you need to call __memset_power7 for the IFUNC optimization
> (st[r/p]ncpy-power7) and __GI_memset/memset (if not SHARED) for non multiarch builds. I fixed
> a similar issue for strncat optimization recently, check de21c33c068c8e39afb5711613a7c083c11ce6a1.
>
More information about the Libc-alpha
mailing list