| 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: | |
| 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 | |
[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.

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