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>
This commit is contained in:
parent
0100ce2b49
commit
bf67aa3dd2
@ -27,7 +27,6 @@
|
|||||||
#include "host/cpuinfo.h"
|
#include "host/cpuinfo.h"
|
||||||
|
|
||||||
typedef bool (*biz_accel_fn)(const void *, size_t);
|
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)
|
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 */
|
#endif /* CONFIG_AVX2_OPT */
|
||||||
|
|
||||||
static unsigned __attribute__((noinline))
|
static biz_accel_fn const accel_table[] = {
|
||||||
select_accel_cpuinfo(unsigned info)
|
buffer_is_zero_int_ge256,
|
||||||
{
|
buffer_zero_sse2,
|
||||||
/* Array is sorted in order of algorithm preference. */
|
|
||||||
static const struct {
|
|
||||||
unsigned bit;
|
|
||||||
biz_accel_fn fn;
|
|
||||||
} all[] = {
|
|
||||||
#ifdef CONFIG_AVX2_OPT
|
#ifdef CONFIG_AVX2_OPT
|
||||||
{ CPUINFO_AVX2, buffer_zero_avx2 },
|
buffer_zero_avx2,
|
||||||
#endif
|
#endif
|
||||||
{ CPUINFO_SSE2, buffer_zero_sse2 },
|
};
|
||||||
{ CPUINFO_ALWAYS, buffer_is_zero_int_ge256 },
|
|
||||||
};
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(all); ++i) {
|
static unsigned best_accel(void)
|
||||||
if (info & all[i].bit) {
|
{
|
||||||
buffer_is_zero_accel = all[i].fn;
|
unsigned info = cpuinfo_init();
|
||||||
return all[i].bit;
|
|
||||||
}
|
#ifdef CONFIG_AVX2_OPT
|
||||||
|
if (info & CPUINFO_AVX2) {
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
return 0;
|
#endif
|
||||||
|
return info & CPUINFO_SSE2 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned used_accel;
|
|
||||||
|
|
||||||
static void __attribute__((constructor)) init_accel(void)
|
|
||||||
{
|
|
||||||
used_accel = select_accel_cpuinfo(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
|
#else
|
||||||
bool test_buffer_is_zero_next_accel(void)
|
#define best_accel() 0
|
||||||
{
|
static biz_accel_fn const accel_table[1] = {
|
||||||
return false;
|
buffer_is_zero_int_ge256
|
||||||
}
|
};
|
||||||
|
|
||||||
#define INIT_ACCEL buffer_is_zero_int_ge256
|
|
||||||
#endif
|
#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)
|
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);
|
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];
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user