Skip to content

Commit

Permalink
PowerPC: memset optimization for POWER8/PPC64
Browse files Browse the repository at this point in the history
This patch adds an optimized memset implementation for POWER8.  For
sizes from 0 to 255 bytes, a word/doubleword algorithm similar to
POWER7 optimized one is used.

For size higher than 255 two strategies are used:

1. If the constant is different than 0, the memory is written with
   altivec vector instruction;

2. If constant is 0, dbcz instructions are used.  The loop is unrolled
   to clear 512 byte at time.

Using vector instructions increases throughput considerable, with a
double performance for sizes larger than 1024.  The dcbz loops unrolls
also shows performance improvement, by doubling throughput for sizes
larger than 8192 bytes.
  • Loading branch information
Adhemerval Zanella committed Sep 10, 2014
1 parent 3b473fe commit 71ae864
Show file tree
Hide file tree
Showing 8 changed files with 533 additions and 9 deletions.
15 changes: 15 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
2014-09-10 Adhemerval Zanella <azanella@linux.vnet.ibm.com>

* benchtests/bench-memset.c (test_main): Add more test from size
from 32 to 512 bytes.
* sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]:
Add POWER8 memset object.
* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
(__libc_ifunc_impl_list): Add POWER8 memset and bzero implementations.
* sysdeps/powerpc/powerpc64/multiarch/bzero.c (__bzero): Add POWER8
implementation.
* sysdeps/powerpc/powerpc64/multiarch/memset.c (__libc_memset):
Likewise.
* sysdeps/powerpc/powerpc64/multiarch/memset-power8.S: New file:
multiarch POWER8 memset optimization.
* sysdeps/powerpc/powerpc64/power8/memset.S: New file: optimized
POWER8 memset optimization.

* sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]:
Remove bzero multiarch objects.
* sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S: Remove file.
Expand Down
5 changes: 5 additions & 0 deletions benchtests/bench-memset.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ test_main (void)
if (i & (i - 1))
do_test (0, c, i);
}
for (i = 32; i < 512; i+=32)
{
do_test (0, c, i);
do_test (i, c, i);
}
do_test (1, c, 14);
do_test (3, c, 1024);
do_test (4, c, 64);
Expand Down
2 changes: 1 addition & 1 deletion sysdeps/powerpc/powerpc64/multiarch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ifeq ($(subdir),string)
sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \
memcmp-ppc64 memset-power7 memset-power6 memset-power4 \
memset-ppc64 \
memset-ppc64 memset-power8 \
mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
Expand Down
11 changes: 7 additions & 4 deletions sysdeps/powerpc/powerpc64/multiarch/bzero.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ extern __typeof (bzero) __bzero_ppc attribute_hidden;
extern __typeof (bzero) __bzero_power4 attribute_hidden;
extern __typeof (bzero) __bzero_power6 attribute_hidden;
extern __typeof (bzero) __bzero_power7 attribute_hidden;
extern __typeof (bzero) __bzero_power8 attribute_hidden;

libc_ifunc (__bzero,
(hwcap & PPC_FEATURE_HAS_VSX)
? __bzero_power7 :
(hwcap & PPC_FEATURE_ARCH_2_05)
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
? __bzero_power8 :
(hwcap & PPC_FEATURE_HAS_VSX)
? __bzero_power7 :
(hwcap & PPC_FEATURE_ARCH_2_05)
? __bzero_power6 :
(hwcap & PPC_FEATURE_POWER4)
? __bzero_power4
? __bzero_power4
: __bzero_ppc);

weak_alias (__bzero, bzero)
Expand Down
6 changes: 6 additions & 0 deletions sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t i = 0;

unsigned long int hwcap = GLRO(dl_hwcap);
unsigned long int hwcap2 = GLRO(dl_hwcap2);

/* hwcap contains only the latest supported ISA, the code checks which is
and fills the previous supported ones. */
if (hwcap & PPC_FEATURE_ARCH_2_06)
Expand Down Expand Up @@ -69,6 +71,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,

/* Support sysdeps/powerpc/powerpc64/multiarch/memset.c. */
IFUNC_IMPL (i, name, memset,
IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07,
__memset_power8)
IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX,
__memset_power7)
IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05,
Expand Down Expand Up @@ -134,6 +138,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,

/* Support sysdeps/powerpc/powerpc64/multiarch/bzero.c. */
IFUNC_IMPL (i, name, bzero,
IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07,
__bzero_power8)
IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX,
__bzero_power7)
IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05,
Expand Down
43 changes: 43 additions & 0 deletions sysdeps/powerpc/powerpc64/multiarch/memset-power8.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Optimized memset implementation for PowerPC64/POWER8.
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>

#undef EALIGN
#define EALIGN(name, alignt, words) \
.section ".text"; \
ENTRY_2(__memset_power8) \
.align ALIGNARG(alignt); \
EALIGN_W_##words; \
BODY_LABEL(__memset_power8): \
cfi_startproc; \
LOCALENTRY(__memset_power8)

#undef END_GEN_TB
#define END_GEN_TB(name, mask) \
cfi_endproc; \
TRACEBACK_MASK(__memset_power8,mask) \
END_2(__memset_power8)

#undef libc_hidden_builtin_def
#define libc_hidden_builtin_def(name)

#undef __bzero
#define __bzero __bzero_power8

#include <sysdeps/powerpc/powerpc64/power8/memset.S>
11 changes: 7 additions & 4 deletions sysdeps/powerpc/powerpc64/multiarch/memset.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ extern __typeof (__redirect_memset) __memset_ppc attribute_hidden;
extern __typeof (__redirect_memset) __memset_power4 attribute_hidden;
extern __typeof (__redirect_memset) __memset_power6 attribute_hidden;
extern __typeof (__redirect_memset) __memset_power7 attribute_hidden;
extern __typeof (__redirect_memset) __memset_power8 attribute_hidden;

/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
ifunc symbol properly. */
libc_ifunc (__libc_memset,
(hwcap & PPC_FEATURE_HAS_VSX)
? __memset_power7 :
(hwcap & PPC_FEATURE_ARCH_2_05)
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
? __memset_power8 :
(hwcap & PPC_FEATURE_HAS_VSX)
? __memset_power7 :
(hwcap & PPC_FEATURE_ARCH_2_05)
? __memset_power6 :
(hwcap & PPC_FEATURE_POWER4)
? __memset_power4
? __memset_power4
: __memset_ppc);

#undef memset
Expand Down
Loading

0 comments on commit 71ae864

Please sign in to comment.