Bug #119076 new ut_delay
Submitted: 26 Sep 9:11 Modified: 30 Sep 16:41
Reporter: Alex Zimnitski Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S4 (Feature request)
Version:5.7.43, 8.0.40, 8.4 OS:Any
Assigned to: CPU Architecture:x86

[26 Sep 9:11] Alex Zimnitski
Description:
There's no point in leaving code 
j += i;
in place just to avoid the compiler's optimizer.

Current code on a CPU with a small number of cores and a large number of running threads overloads CPU registers.

I recommend new code for the function. The default multiplier is 50, and almost no one changes it. You can fix it to a multiple of 10.

How to repeat:
Current code

ulint ut_delay(ulint delay) {
  ulint i, j;
  /* We don't expect overflow here, as ut::spin_wait_pause_multiplier is limited
  to 100, and values of delay are not larger than @@innodb_spin_wait_delay
  which is limited by 1 000. Anyway, in case an overflow happened, the program
  would still work (as iterations is unsigned). */
  const ulint iterations = delay * ut::spin_wait_pause_multiplier;
  UT_LOW_PRIORITY_CPU();

  j = 0;

  for (i = 0; i < iterations; i++) {
    j += i;
    UT_RELAX_CPU();
  }

  UT_RESUME_PRIORITY_CPU();

  return (j);
}

Suggested fix:
New code

ut0ut.cc
#pragma GCC push_options
#pragma GCC optimize ("O0")
void __attribute__((optimize("O0"))) ut_delay(ulint delay) {
  volatile ulint i;
  const ulint iterations = delay * ut::spin_wait_pause_multiplier;

  UT_LOW_PRIORITY_CPU();

  for (i = 0; i < iterations; i+=10) {
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
    UT_RELAX_CPU();
  }

  UT_RESUME_PRIORITY_CPU();
}
#pragma GCC pop_options
[29 Sep 13:04] MySQL Verification Team
Thank you very much for your patch contribution, we appreciate it!

In order for us to continue the process of reviewing your contribution to MySQL, please send us a signed copy of the Oracle Contributor Agreement (OCA) as outlined in https://oca.opensource.oracle.com

Signing an OCA needs to be done only once and it's valid for all other Oracle governed Open Source projects as well.

Getting a signed/approved OCA on file will help us facilitate your contribution - this one, and others in the future.  

Please let me know, if you have any questions.

Thank you for your interest in MySQL.