From f7a1cddb3d2692066b6507e704a30b518569f63d Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 1 Mar 2017 16:51:10 +0300 Subject: [PATCH] Bug #79454: Inefficient InnoDB row stats implementation Use PRNG-based slot indexes for InnoDB row counters on AArch64. Using RDTSC- (aka counter-based) indexes result in higher contention on many-core AArch64 machines due to low timer resolution (100 MHz). Using sched_getcpu()-based indexers leads to lower single-threaded performance, because sched_getcpu() is expensive on AArch64 (it is not implemented via VDSO like on x86). This also requires a better quality PRNG and properly seeding it for each thread. These will be addressed in separate patches. --- storage/innobase/include/sync0types.h | 1 - storage/innobase/include/ut0counter.h | 23 ++++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index 2c11fc5..f504d68 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -30,7 +30,6 @@ Created 9/5/1995 Heikki Tuuri #include #include "ut0new.h" -#include "ut0counter.h" #if defined(UNIV_DEBUG) && !defined(UNIV_INNOCHECKSUM) /** Set when InnoDB has invoked exit(). */ diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h index 6b187ec..8c163d0 100644 --- a/storage/innobase/include/ut0counter.h +++ b/storage/innobase/include/ut0counter.h @@ -30,6 +30,7 @@ Created 2012/04/12 by Sunny Bains #include #include "univ.i" #include "os0thread.h" +#include "ut0rnd.h" /** CPU cache line size */ #ifdef __powerpc__ @@ -53,6 +54,22 @@ struct generic_indexer_t { } }; +/** Use random numbers to index into the counter array. */ +template +struct get_rand_indexer_t : public generic_indexer_t { + /** Default constructor/destructor should be OK. */ + + enum { fast = 1 }; + + /* @return result from ut_rnd_gen_ulint(). */ + static size_t get_rnd_index() UNIV_NOTHROW { + + ulint idx = ut_rnd_gen_ulint(); + + return(size_t(idx)); + } +}; + /** Use the result of my_timer_cycles(), which mainly uses RDTSC for cycles, to index into the counter array. See the comments for my_timer_cycles() */ template @@ -106,7 +123,11 @@ struct single_indexer_t { } }; -#define default_indexer_t counter_indexer_t +#if defined(__aarch64__) && defined(UNIV_LINUX) +# define default_indexer_t get_rand_indexer_t +#else +# define default_indexer_t counter_indexer_t +#endif /** Class for using fuzzy counters. The counter is not protected by any mutex and the results are not guaranteed to be 100% accurate but close