Bug #72806 mutex_delay() missing x86 pause instruction optimization
Submitted: 30 May 2014 6:43 Modified: 29 Apr 2015 0:11
Reporter: Stewart Smith Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Compiling Severity:S5 (Performance)
Version:5.7.7 OS:Any
Assigned to: CPU Architecture:Any
Tags: Intel, mutex, pause, performance, spinlock

[30 May 2014 6:43] Stewart Smith
Description:
The delay function in mysys/thr_mutex.c (introduced in 5.7) looks roughly like this:

ulong mutex_delay(ulong delayloops)
{
  ulong i;
  volatile ulong j;

  j = 0;

  for (i = 0; i < delayloops * 50; i++)
  {
    j += i;
  }
  
  return(j);
}

Which misses using the x86 PAUSE instruction to tell the CPU that we're in a spinloop and to give priority of CPU resources to other executing threads as they will be able to do useful work.

This is a regression over 5.6 as in 5.6 InnoDB uses the UT_RELAX_CPU() macro to properly insert the PAUSE instruction.

How to repeat:
code audit!

Suggested fix:
Similar define to InnoDB in 5.6.
[30 May 2014 8:59] MySQL Verification Team
Hello Stewart,

Thank you for the report.

Thanks,
Umesh
[13 Nov 2014 6:20] Stewart Smith
5.7.5-m15 is also affected.

My patch in http://bugs.mysql.com/bug.php?id=72805 resolves everything in an ideal manner for POWER. Adding x86 PAUSE instruction there is left up to the reader (but should be trivial).
[10 Apr 2015 7:55] Stewart Smith
Still see this in 5.7.7

This code is just so horrifically wrong without these fixes it's not funny. Just using libc pthread_mutexes will *ALWAYS* be better than this code.
[29 Apr 2015 0:11] Paul DuBois
Noted in 5.7.8 changelog.

The so-called "fast mutex" code has been removed from the server
sources. It provides no measurable benefit, complicates the code, and
is problematic for certain architectures such as POWER8. The
(undocumented) WITH_FAST_MUTEXES CMake option has also been removed.