Commit 41e6a154 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-14482 - Cache line contention on ut_rnd_interval()

InnoDB RNG maintains global state, causing otherwise unnecessary bus
traffic. Even worse, this is cross-mutex traffic. That is, different
mutexes suffer from contention.

Fixed delay of 4 was verified to give best throughput by OLTP update
index and read-write benchmarks on Intel Broadwell (2/20/40) and
ARM (1/46/46).

This is a backport of ce047900 from
MariaDB Server 10.3.
parent b1f2d3a8
SET @start_global_value = @@global.innodb_spin_wait_delay;
SELECT @start_global_value;
@start_global_value
6
4
Valid values are zero or above
select @@global.innodb_spin_wait_delay >=0;
@@global.innodb_spin_wait_delay >=0
1
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
6
4
select @@session.innodb_spin_wait_delay;
ERROR HY000: Variable 'innodb_spin_wait_delay' is a GLOBAL variable
show global variables like 'innodb_spin_wait_delay';
Variable_name Value
innodb_spin_wait_delay 6
innodb_spin_wait_delay 4
show session variables like 'innodb_spin_wait_delay';
Variable_name Value
innodb_spin_wait_delay 6
innodb_spin_wait_delay 4
select * from information_schema.global_variables where variable_name='innodb_spin_wait_delay';
VARIABLE_NAME VARIABLE_VALUE
INNODB_SPIN_WAIT_DELAY 6
INNODB_SPIN_WAIT_DELAY 4
select * from information_schema.session_variables where variable_name='innodb_spin_wait_delay';
VARIABLE_NAME VARIABLE_VALUE
INNODB_SPIN_WAIT_DELAY 6
INNODB_SPIN_WAIT_DELAY 4
set global innodb_spin_wait_delay=10;
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
......@@ -38,7 +38,7 @@ ERROR HY000: Variable 'innodb_spin_wait_delay' is a GLOBAL variable and should b
set global innodb_spin_wait_delay=DEFAULT;
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
6
4
set global innodb_spin_wait_delay=0;
select @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
......@@ -111,4 +111,4 @@ INNODB_SPIN_WAIT_DELAY 0
SET @@global.innodb_spin_wait_delay = @start_global_value;
SELECT @@global.innodb_spin_wait_delay;
@@global.innodb_spin_wait_delay
6
4
......@@ -2228,10 +2228,10 @@ READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_SPIN_WAIT_DELAY
SESSION_VALUE NULL
DEFAULT_VALUE 6
DEFAULT_VALUE 4
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Maximum delay between polling for a spin lock (6 by default)
VARIABLE_COMMENT Maximum delay between polling for a spin lock (4 by default)
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 6000
NUMERIC_BLOCK_SIZE 0
......
......@@ -20716,8 +20716,8 @@ static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
static MYSQL_SYSVAR_UINT(spin_wait_delay, srv_spin_wait_delay,
PLUGIN_VAR_OPCMDARG,
"Maximum delay between polling for a spin lock (6 by default)",
NULL, NULL, 6, 0, 6000, 0);
"Maximum delay between polling for a spin lock (4 by default)",
NULL, NULL, 4, 0, 6000, 0);
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
......
......@@ -225,7 +225,7 @@ struct TTASFutexMutex {
return;
}
ut_delay(ut_rnd_interval(max_delay));
ut_delay(max_delay);
}
for (n_waits= 0;; n_waits++) {
......@@ -362,7 +362,7 @@ struct TTASMutex {
uint32_t n_spins = 0;
while (!try_lock()) {
ut_delay(ut_rnd_interval(max_delay));
ut_delay(max_delay);
if (++n_spins == max_spins) {
os_thread_yield();
max_spins+= step;
......@@ -516,7 +516,7 @@ struct TTASEventMutex {
sync_array_wait_event(sync_arr, cell);
}
} else {
ut_delay(ut_rnd_interval(max_delay));
ut_delay(max_delay);
}
}
......
......@@ -298,10 +298,7 @@ rw_lock_s_lock_spin(
/* Spin waiting for the writer field to become free */
HMT_low();
while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(srv_spin_wait_delay));
}
ut_delay(srv_spin_wait_delay);
i++;
}
......@@ -420,13 +417,9 @@ rw_lock_x_lock_wait_func(
ut_ad(lock->lock_word <= threshold);
HMT_low();
while (lock->lock_word < threshold) {
HMT_low();
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(srv_spin_wait_delay));
}
ut_delay(srv_spin_wait_delay);
if (i < srv_n_spin_wait_rounds) {
i++;
......@@ -683,10 +676,7 @@ rw_lock_x_lock_func(
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(srv_spin_wait_delay));
}
ut_delay(srv_spin_wait_delay);
i++;
}
......@@ -788,10 +778,7 @@ rw_lock_sx_lock_func(
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(srv_spin_wait_delay));
}
ut_delay(srv_spin_wait_delay);
i++;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment