diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-02-14 21:10:56 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-05-03 08:03:05 -0700 |
commit | bf67aa3dd2d8b28d7618d8ec62cd9f6055366751 (patch) | |
tree | bee88905b81022aacb1b3d95cf2f4504012ca073 /util | |
parent | 0100ce2b49725e6ba2fbe8301855978d5d3dc790 (diff) | |
download | qemu-bf67aa3dd2d8b28d7618d8ec62cd9f6055366751.zip qemu-bf67aa3dd2d8b28d7618d8ec62cd9f6055366751.tar.gz qemu-bf67aa3dd2d8b28d7618d8ec62cd9f6055366751.tar.bz2 |
util/bufferiszero: Simplify test_buffer_is_zero_next_accel
Because the three alternatives are monotonic, we don't need
to keep a couple of bitmasks, just identify the strongest
alternative at startup.
Generalize test_buffer_is_zero_next_accel and init_accel
by always defining an accel_table array.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'util')
-rw-r--r-- | util/bufferiszero.c | 81 |
1 files changed, 35 insertions, 46 deletions
diff --git a/util/bufferiszero.c b/util/bufferiszero.c index f9af784..7218154 100644 --- a/util/bufferiszero.c +++ b/util/bufferiszero.c @@ -27,7 +27,6 @@ #include "host/cpuinfo.h" typedef bool (*biz_accel_fn)(const void *, size_t); -static biz_accel_fn buffer_is_zero_accel; static bool buffer_is_zero_int_lt256(const void *buf, size_t len) { @@ -179,60 +178,35 @@ buffer_zero_avx2(const void *buf, size_t len) } #endif /* CONFIG_AVX2_OPT */ -static unsigned __attribute__((noinline)) -select_accel_cpuinfo(unsigned info) -{ - /* Array is sorted in order of algorithm preference. */ - static const struct { - unsigned bit; - biz_accel_fn fn; - } all[] = { +static biz_accel_fn const accel_table[] = { + buffer_is_zero_int_ge256, + buffer_zero_sse2, #ifdef CONFIG_AVX2_OPT - { CPUINFO_AVX2, buffer_zero_avx2 }, + buffer_zero_avx2, #endif - { CPUINFO_SSE2, buffer_zero_sse2 }, - { CPUINFO_ALWAYS, buffer_is_zero_int_ge256 }, - }; +}; - for (unsigned i = 0; i < ARRAY_SIZE(all); ++i) { - if (info & all[i].bit) { - buffer_is_zero_accel = all[i].fn; - return all[i].bit; - } - } - return 0; -} - -static unsigned used_accel; - -static void __attribute__((constructor)) init_accel(void) +static unsigned best_accel(void) { - used_accel = select_accel_cpuinfo(cpuinfo_init()); -} + unsigned info = cpuinfo_init(); -#define INIT_ACCEL NULL - -bool test_buffer_is_zero_next_accel(void) -{ - /* - * Accumulate the accelerators that we've already tested, and - * remove them from the set to test this round. We'll get back - * a zero from select_accel_cpuinfo when there are no more. - */ - unsigned used = select_accel_cpuinfo(cpuinfo & ~used_accel); - used_accel |= used; - return used; -} -#else -bool test_buffer_is_zero_next_accel(void) -{ - return false; +#ifdef CONFIG_AVX2_OPT + if (info & CPUINFO_AVX2) { + return 2; + } +#endif + return info & CPUINFO_SSE2 ? 1 : 0; } -#define INIT_ACCEL buffer_is_zero_int_ge256 +#else +#define best_accel() 0 +static biz_accel_fn const accel_table[1] = { + buffer_is_zero_int_ge256 +}; #endif -static biz_accel_fn buffer_is_zero_accel = INIT_ACCEL; +static biz_accel_fn buffer_is_zero_accel; +static unsigned accel_index; bool buffer_is_zero_ool(const void *buf, size_t len) { @@ -257,3 +231,18 @@ bool buffer_is_zero_ge256(const void *buf, size_t len) { return buffer_is_zero_accel(buf, len); } + +bool test_buffer_is_zero_next_accel(void) +{ + if (accel_index != 0) { + buffer_is_zero_accel = accel_table[--accel_index]; + return true; + } + return false; +} + +static void __attribute__((constructor)) init_accel(void) +{ + accel_index = best_accel(); + buffer_is_zero_accel = accel_table[accel_index]; +} |