diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2014-02-28 16:03:04 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-03-01 20:15:59 +0000 |
commit | e381585619778c4952ada5f3118ec4fcf304eb66 (patch) | |
tree | 412fadab6f9d52a25fe328bc5f6e34cddbf88d04 /common/util.c | |
parent | a35bfd69e9a749fbaa152937dd91a6ed407a9005 (diff) | |
download | chrome-ec-e381585619778c4952ada5f3118ec4fcf304eb66.tar.gz |
Optimize memset
This speeds up memset by copying a word at a time.
Ran the unit test on Peppy:
> runtest
...
Running test_memset... (speed gain: 141532 -> 32136 us) OK
...
Ran make buildall:
...
Running test_memset... (speed gain: 1338 -> 280 us) OK
...
TEST=Described above.
BUG=chrome-os-partner:23720
BRANCH=none
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Change-Id: If34b06ad70f448d950535a4bea4f6556627a9b6f
Tested-by: Daisuke Nojiri <dnojiri@google.com>
Reviewed-on: https://chromium-review.googlesource.com/185936
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Queue: Daisuke Nojiri <dnojiri@google.com>
Diffstat (limited to 'common/util.c')
-rw-r--r-- | common/util.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/common/util.c b/common/util.c index 5158d8aa06..f8a0519f17 100644 --- a/common/util.c +++ b/common/util.c @@ -217,15 +217,38 @@ void *memcpy(void *dest, const void *src, int len) void *memset(void *dest, int c, int len) { - /* - * TODO(crosbug.com/p/23720): if dest is aligned, copy a word at a time - * instead. - */ char *d = (char *)dest; - while (len > 0) { + uint32_t cccc; + uint32_t *dw; + char *head; + char * const tail = (char *)dest + len; + /* Set 'body' to the last word boundary */ + uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3); + + c &= 0xff; /* Clear upper bits before ORing below */ + cccc = c | (c << 8) | (c << 16) | (c << 24); + + if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) + /* len is shorter than the first word boundary */ + head = tail; + else + /* Set 'head' to the first word boundary */ + head = (char *)(((uintptr_t)d + 3) & ~3); + + /* Copy head */ + while (d < head) *(d++) = c; - len--; - } + + /* Copy body */ + dw = (uint32_t *)d; + while (dw < body) + *(dw++) = cccc; + + /* Copy tail */ + d = (char *)dw; + while (d < tail) + *(d++) = c; + return dest; } |