Introduce a benchmark to compare the architecture-optimized strrchr() implementation against the generic C version (__generic_strrchr).
Suggested-by: Andy Shevchenko <[email protected]> Signed-off-by: Feng Jiang <[email protected]> --- lib/tests/string_kunit.c | 50 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c index e8d527336030..89b583cec2c8 100644 --- a/lib/tests/string_kunit.c +++ b/lib/tests/string_kunit.c @@ -21,7 +21,7 @@ #define STRING_TEST_MAX_OFFSET 16 #if defined(__HAVE_ARCH_STRLEN) || defined(__HAVE_ARCH_STRNLEN) || \ - defined(__HAVE_ARCH_STRCHR) + defined(__HAVE_ARCH_STRCHR) || defined(__HAVE_ARCH_STRRCHR) #define STRING_BENCH_ENABLED #endif @@ -444,6 +444,51 @@ static void string_test_strnchr(struct kunit *test) KUNIT_ASSERT_NULL(test, result); } +#ifdef __HAVE_ARCH_STRRCHR +static void string_test_strrchr_bench(struct kunit *test) +{ + char *buf; + size_t buf_len, iters; + ktime_t start, end; + u64 time_arch, time_generic; + + buf_len = get_max_bench_len(bench_cases, ARRAY_SIZE(bench_cases)) + 1; + + buf = kunit_kzalloc(test, buf_len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); + + for (size_t i = 0; i < ARRAY_SIZE(bench_cases); i++) { + get_random_nonzero_bytes(buf, bench_cases[i].len); + if (bench_cases[i].len > 0) + buf[bench_cases[i].len - 1] = 'A'; + buf[bench_cases[i].len] = '\0'; + + iters = bench_cases[i].iterations; + + /* 1. Benchmark the architecture-optimized version */ + start = ktime_get(); + for (unsigned int j = 0; j < iters; j++) { + OPTIMIZER_HIDE_VAR(buf); + (void)strrchr(buf, 'A'); + } + end = ktime_get(); + time_arch = ktime_to_ns(ktime_sub(end, start)); + + /* 2. Benchmark the generic C version */ + start = ktime_get(); + for (unsigned int j = 0; j < iters; j++) { + OPTIMIZER_HIDE_VAR(buf); + (void)__generic_strrchr(buf, 'A'); + } + end = ktime_get(); + time_generic = ktime_to_ns(ktime_sub(end, start)); + + string_bench_report(test, "strrchr", &bench_cases[i], + time_arch, time_generic); + } +} +#endif + static void string_test_strspn(struct kunit *test) { static const struct strspn_test { @@ -916,6 +961,9 @@ static struct kunit_case string_test_cases[] = { #endif KUNIT_CASE(string_test_strnchr), KUNIT_CASE(string_test_strrchr), +#ifdef __HAVE_ARCH_STRRCHR + KUNIT_CASE(string_test_strrchr_bench), +#endif KUNIT_CASE(string_test_strspn), KUNIT_CASE(string_test_strcmp), KUNIT_CASE(string_test_strcmp_long_strings), -- 2.25.1
