From af2606354a8e166e4cdb7fc1c24762f00d712733 Mon Sep 17 00:00:00 2001 From: Yasufumi Kinoshita Date: Fri, 4 Mar 2016 13:34:26 +1100 Subject: [PATCH 1/2] Some POWER specific optimizations Bug#18842925 : SET THREAD PRIORITY IN INNODB MUTEX SPINLOOP Like "pause" instruction for hyper-threading at Intel CPUs, POWER has special instructions only for hinting priority of hardware-threads. Bug#18814859 : "CACHE_LINE_SIZE IN INNODB SHOULD BE 128 ON POWER") Data arrangement is be better to be conscious about data-cache unit size of CPU, for more CPU cache consistency. Currently it is fixed to 64 bytes in InnoDB, but 128 bytes is better for POWER. Approved by Sunny in rb#6256 Backport of the 5.7 fix - https://github.com/mysql/mysql-server/commit/c92102a6ef0f280bfb56e5585fca0d0cdcc34890 --- config.h.cmake | 1 + configure.cmake | 10 ++++++++++ storage/innobase/include/ut0counter.h | 4 ++++ storage/innobase/include/ut0ut.h | 8 ++++++++ storage/innobase/ut/ut0ut.cc | 4 ++++ 5 files changed, 27 insertions(+) diff --git a/config.h.cmake b/config.h.cmake index 5b7445f..d8d64b9 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -208,6 +208,7 @@ #cmakedefine HAVE_PREAD 1 #cmakedefine HAVE_PAUSE_INSTRUCTION 1 #cmakedefine HAVE_FAKE_PAUSE_INSTRUCTION 1 +#cmakedefine HAVE_HMT_PRIORITY_INSTRUCTION 1 #cmakedefine HAVE_RDTSCLL 1 #cmakedefine HAVE_READ_REAL_TIME 1 #cmakedefine HAVE_PTHREAD_ATTR_CREATE 1 diff --git a/configure.cmake b/configure.cmake index 797fad7..c47ee7d 100644 --- a/configure.cmake +++ b/configure.cmake @@ -1002,6 +1002,16 @@ IF(NOT CMAKE_CROSSCOMPILING AND NOT MSVC) } " HAVE_FAKE_PAUSE_INSTRUCTION) ENDIF() + IF (NOT HAVE_PAUSE_INSTRUCTION) + CHECK_C_SOURCE_COMPILES(" + int main() + { + __asm__ __volatile__ ("or 1,1,1"); + __asm__ __volatile__ ("or 2,2,2"); + return 0; + } + " HAVE_HMT_PRIORITY_INSTRUCTION) + ENDIF() ENDIF() CHECK_SYMBOL_EXISTS(tcgetattr "termios.h" HAVE_TCGETATTR 1) diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h index fe0f36d..7432df5 100644 --- a/storage/innobase/include/ut0counter.h +++ b/storage/innobase/include/ut0counter.h @@ -32,7 +32,11 @@ Created 2012/04/12 by Sunny Bains #include "os0thread.h" /** CPU cache line size */ +#ifdef __powerpc__ +#define CACHE_LINE_SIZE 128 +#else #define CACHE_LINE_SIZE 64 +#endif /* __powerpc__ */ /** Default number of slots to use in ib_counter_t */ #define IB_N_SLOTS 64 diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 0caf379..35546c7 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -92,6 +92,14 @@ struct ut_when_dtor { # define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */ # endif +# if defined(HAVE_HMT_PRIORITY_INSTRUCTION) +# define UT_LOW_PRIORITY_CPU() __asm__ __volatile__ ("or 1,1,1") +# define UT_RESUME_PRIORITY_CPU() __asm__ __volatile__ ("or 2,2,2") +# else +# define UT_LOW_PRIORITY_CPU() ((void)0) +# define UT_RESUME_PRIORITY_CPU() ((void)0) +# endif + /*********************************************************************//** Delays execution for at most max_wait_us microseconds or returns earlier if cond becomes true. diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 68446cc..616ac2d 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -403,6 +403,8 @@ ut_delay( { ulint i, j; + UT_LOW_PRIORITY_CPU(); + j = 0; for (i = 0; i < delay * 50; i++) { @@ -414,6 +416,8 @@ ut_delay( ut_always_false = (ibool) j; } + UT_RESUME_PRIORITY_CPU(); + return(j); } #endif /* !UNIV_HOTBACKUP */ From f99ba52723307a0c1dc01b00352957defe3e4b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 4 Mar 2016 13:37:31 +1100 Subject: [PATCH 2/2] Bug#20045167 UT_DELAY MISSING COMPILER BARRIER UT_RELAX_CPU(): Use a compiler barrier. ut_delay(): Remove the dummy global variable ut_always_false. RB: 11399 Reviewed-by: Jimmy Yang Backported from MySQL-5.7 - patch https://github.com/mysql/mysql-server/commit/5e3efb03962838a13afbf1579abbb96aee48ad64 --- storage/innobase/include/ut0ut.h | 5 +---- storage/innobase/ut/ut0ut.cc | 7 ------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 35546c7..13eaf10 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -79,10 +79,7 @@ struct ut_when_dtor { # elif defined(HAVE_FAKE_PAUSE_INSTRUCTION) # define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop") # elif defined(HAVE_ATOMIC_BUILTINS) -# define UT_RELAX_CPU() do { - volatile lint volatile_var; - os_compare_and_swap_lint(&volatile_var, 0, 1); - } while (0) +# define UT_RELAX_CPU() __asm__ __volatile__ ("":::"memory") # elif defined(HAVE_WINDOWS_ATOMICS) /* In the Win32 API, the x86 PAUSE instruction is executed by calling the YieldProcessor macro defined in WinNT.h. It is a CPU architecture- diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 616ac2d..efc6232 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -44,9 +44,6 @@ Created 5/11/1994 Heikki Tuuri # include "mysql_com.h" /* NAME_LEN */ #endif /* UNIV_HOTBACKUP */ -/** A constant to prevent the compiler from optimizing ut_delay() away. */ -UNIV_INTERN ibool ut_always_false = FALSE; - #ifdef __WIN__ /*****************************************************************//** NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix @@ -412,10 +409,6 @@ ut_delay( UT_RELAX_CPU(); } - if (ut_always_false) { - ut_always_false = (ibool) j; - } - UT_RESUME_PRIORITY_CPU(); return(j);