From acf81a4bc8908c40bfb197e1ceb5ca5f2a5993a1 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 1 Dec 2017 14:49:42 -0700 Subject: [PATCH] memcpy: add hybrid Use builtin memcpy for < 64 bytes, use simple variant for larger ones. libc doesn't seem to like to use SSE, the hand rolled simple variant uses that for larger copies. Signed-off-by: Jens Axboe --- lib/memcpy.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/memcpy.c b/lib/memcpy.c index 48484390..00e65aa7 100644 --- a/lib/memcpy.c +++ b/lib/memcpy.c @@ -72,16 +72,17 @@ static struct memcpy_test tests[] = { struct memcpy_type { const char *name; unsigned int mask; - void (*fn)(struct memcpy_type *, struct memcpy_test *); + void (*fn)(struct memcpy_test *); }; enum { T_MEMCPY = 1U << 0, T_MEMMOVE = 1U << 1, T_SIMPLE = 1U << 2, + T_HYBRID = 1U << 3, }; -#define do_test(t, test, fn) do { \ +#define do_test(test, fn) do { \ size_t left, this; \ void *src, *dst; \ int i; \ @@ -102,14 +103,14 @@ enum { } \ } while (0) -static void t_memcpy(struct memcpy_type *t, struct memcpy_test *test) +static void t_memcpy(struct memcpy_test *test) { - do_test(t, test, memcpy); + do_test(test, memcpy); } -static void t_memmove(struct memcpy_type *t, struct memcpy_test *test) +static void t_memmove(struct memcpy_test *test) { - do_test(t, test, memmove); + do_test(test, memmove); } static void simple_memcpy(void *dst, void const *src, size_t len) @@ -121,9 +122,17 @@ static void simple_memcpy(void *dst, void const *src, size_t len) *d++ = *s++; } -static void t_simple(struct memcpy_type *t, struct memcpy_test *test) +static void t_simple(struct memcpy_test *test) { - do_test(t, test, simple_memcpy); + do_test(test, simple_memcpy); +} + +static void t_hybrid(struct memcpy_test *test) +{ + if (test->size >= 64) + do_test(test, simple_memcpy); + else + do_test(test, memcpy); } static struct memcpy_type t[] = { @@ -142,7 +151,11 @@ static struct memcpy_type t[] = { .mask = T_SIMPLE, .fn = t_simple, }, - + { + .name = "hybrid", + .mask = T_HYBRID, + .fn = t_hybrid, + }, { .name = NULL, }, @@ -248,13 +261,13 @@ int fio_memcpy_test(const char *type) * we've touched the data. */ usec_spin(100000); - t[i].fn(&t[i], &tests[0]); + t[i].fn(&tests[0]); printf("%s\n", t[i].name); for (j = 0; tests[j].name; j++) { fio_gettime(&ts, NULL); - t[i].fn(&t[i], &tests[j]); + t[i].fn(&tests[j]); usec = utime_since_now(&ts); if (usec) { -- 2.25.1