diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-06-01 14:34:47 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-06-01 17:10:10 +1000 |
commit | f232117367198c330ddf64a4c61bda0110ae9cec (patch) | |
tree | 098556ac2e6b4488e7bfb0012d769be1f68d292b /libc/string | |
parent | 3bd6f3ba4a2070ab42647a0d07770e9828765031 (diff) | |
download | skiboot-f232117367198c330ddf64a4c61bda0110ae9cec.zip skiboot-f232117367198c330ddf64a4c61bda0110ae9cec.tar.gz skiboot-f232117367198c330ddf64a4c61bda0110ae9cec.tar.bz2 |
Optimized memset() implementation for POWER
This uses the dcbz instruction to clear cacheline at a time rather than
byte at a time. This means that even without high levels of optimization,
we *dramatically* improve boot performance with SKIBOOT_GCOV=1 and probably
ever so slightly speed things up for normal builds.
We currently just hard-code 128 as cacheline size as all CPUs that skiboot
currently boots on have 128 byte cachelines.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libc/string')
-rw-r--r-- | libc/string/memset.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/libc/string/memset.c b/libc/string/memset.c index f8dfbf5..18b7619 100644 --- a/libc/string/memset.c +++ b/libc/string/memset.c @@ -12,11 +12,33 @@ #include "string.h" +#define CACHE_LINE_SIZE 128 + void * memset(void *dest, int c, size_t size) { unsigned char *d = (unsigned char *)dest; +#if defined(__powerpc__) || defined(__powerpc64__) + if (size > CACHE_LINE_SIZE && c==0) { + while ((unsigned long long)d % CACHE_LINE_SIZE) { + *d++ = (unsigned char)c; + size--; + } + while (size >= CACHE_LINE_SIZE) { + asm volatile ("dcbz 0,%0\n" : : "r"(d) : "memory"); + d+= CACHE_LINE_SIZE; + size-= CACHE_LINE_SIZE; + } + } +#endif + + while (size >= 8 && c == 0) { + *((unsigned long long*)d) = 0ULL; + d+=8; + size-=8; + } + while (size-- > 0) { *d++ = (unsigned char)c; } |