Status: Open (View Workflow)
While testing MySQL, however same code still in MariaDB, I came across this performance problem where loading the global variables btr_search_enabled. The load of this memory location was a hot point in the code.
It turns out during compilation that btr_search_enabled was placed on a shared cache line address as ut_rnd_ulint_counter and the system was extensively using random numbers. The result is that a critical path of innodb was slow as this global variable was frequently expelled from the CPU caches and access was only granted to read it to one of the CPUs at a time.
This is a more general problem that SQL global variables are mostly read only and there is a proliferation of statistics counters and other static variables that could be innocently placed beside a C++ variable in the linker stage.
To resolve this, a similar mechanism to the linux kernel is used to use attributes to mark global variables that are read_mostly and put them in the same section. Because they are in the same section they are prevented from false sharing with other static variables.
The attached patch demonstrates this concept, however extending this to every global variable would bit rot and be susceptible to merge conflicts.
As an extension to this, global variables that are copied to session variables could also be in their own section so when the start of the global -> session occurs, they are all the same pre-fetched cache-line.
- links to