math: Use cbrtf from CORE-MATH

The CORE-MATH implementation is correctly rounded (for any rounding mode)
and shows better performance to the generic cbrtf.

The code was adapted to glibc style and to use the definition of
math_config.h.

Benchtest on x64_64 (Ryzen 9 5900X, gcc 14.2.1), aarch64 (M1,
gcc 13.2.1), and powerpc (POWER10, gcc 13.2.1):

latency                       master        patched       improvement
x86_64                       68.6348        36.8908            46.25%
x86_64v2                     67.3418        36.6968            45.51%
x86_64v3                     63.4981        32.7859            48.37%
aarch64                      29.3172        12.1496            58.56%
power10                      18.0845         8.8893            50.85%
powerpc                      18.0859        8.79527            51.37%

reciprocal-throughput         master        patched       improvement
x86_64                       36.4369        13.3565            63.34%
x86_64v2                     37.3611        13.1149            64.90%
x86_64v3                     31.6024        11.2102            64.53%
aarch64                      18.6866        7.3474             60.68%
power10                       9.4758        3.6329             61.66%
powerpc                      9.58896        3.90439            59.28%

Signed-off-by: Alexei Sibidanov <sibid@uvic.ca>
Signed-off-by: Paul Zimmermann <Paul.Zimmermann@inria.fr>
Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
Adhemerval Zanella 2024-10-28 12:38:50 -03:00
parent 2234b08763
commit c5d241f06b
26 changed files with 92 additions and 135 deletions

View File

@ -268,3 +268,7 @@ sysdeps/ieee754/flt-32/s_log10p1f.c
(file src/binary32/log10p1/log10p1f.c in CORE-MATH) (file src/binary32/log10p1/log10p1f.c in CORE-MATH)
- The code was adapted to use glibc code style and internal - The code was adapted to use glibc code style and internal
functions to handle errno, overflow, and underflow. functions to handle errno, overflow, and underflow.
sysdeps/ieee754/flt-32/s_cbrtf.c
(file src/binary32/cbrt/cbrtf.c in CORE-MATH)
- The code was adapted to use glibc code style and internal
functions to handle errno, overflow, and underflow.

View File

@ -474,7 +474,6 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_advsimd": Function: "cbrt_advsimd":
@ -483,7 +482,6 @@ float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_sve": Function: "cbrt_sve":
@ -492,12 +490,10 @@ float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -337,19 +337,15 @@ float: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 3 double: 3

View File

@ -84,7 +84,6 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -333,19 +333,15 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -330,19 +330,15 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -328,19 +328,15 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -338,20 +338,16 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -1,61 +1,99 @@
/* Compute cubic root of float value. /* Correctly-rounded cubic root of binary32 value.
Copyright (C) 1997-2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or Copyright (c) 2023, 2024 Alexei Sibidanov.
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, The original version of this file was copied from the CORE-MATH
but WITHOUT ANY WARRANTY; without even the implied warranty of project (file src/binary32/cbrt/cbrtf.c, revision bc385c2).
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public Permission is hereby granted, free of charge, to any person obtaining a copy
License along with the GNU C Library; if not, see of this software and associated documentation files (the "Software"), to deal
<https://www.gnu.org/licenses/>. */ in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
#include <math.h> The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <fenv.h>
#include <libm-alias-float.h> #include <libm-alias-float.h>
#include <math.h>
#include <stdint.h>
#define CBRT2 1.2599210498948731648 /* 2^(1/3) */ #include "math_config.h"
#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
static const double factor[5] =
{
1.0 / SQR_CBRT2,
1.0 / CBRT2,
1.0,
CBRT2,
SQR_CBRT2
};
float float
__cbrtf (float x) __cbrtf (float x)
{ {
float xm, ym, u, t2; static const union
int xe; {
double d;
/* Reduce X. XM now is an range 1.0 to 0.5. */ uint64_t u;
xm = __frexpf (fabsf (x), &xe); } escale[3] =
{
/* If X is not finite or is null return it (with raising exceptions { .d = 1.0 },
if necessary. { .d = 0x1.428a2f98d728bp+0 }, /* 2^(1/3) */
Note: *Our* version of `frexp' sets XE to zero if the argument is { .d = 0x1.965fea53d6e3dp+0 }, /* 2^(2/3) */
Inf or NaN. This is not portable but faster. */ };
if (xe == 0 && fpclassify (x) <= FP_ZERO) uint32_t u = asuint (x);
return x + x; uint32_t au = u << 1;
uint32_t sgn = u >> 31;
u = (0.492659620528969547 + (0.697570460207922770 uint32_t e = au >> 24;
- 0.191502161678719066 * xm) * xm); if (__glibc_unlikely (au < 1u << 24 || au >= 0xffu << 24))
{
t2 = u * u * u; if (au >= 0xffu << 24)
return x + x; /* inf, nan */
ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3]; if (au == 0)
return x; /* +-0 */
return __ldexpf (x > 0.0 ? ym : -ym, xe / 3); int nz = __builtin_clz (au) - 7; /* subnormal */
au <<= nz;
e -= nz - 1;
}
uint32_t mant = au & 0xffffff;
e += 899;
uint32_t et = e / 3, it = e % 3;
uint64_t isc = escale[it].u;
isc += (int64_t) (et - 342) << 52;
isc |= (int64_t) sgn << 63;
double cvt2 = asdouble (isc);
static const double c[] =
{
0x1.2319d352ea5d5p-1, 0x1.67ad8ee258d1ap-1, -0x1.9342edf9cbad9p-2,
0x1.b6388fc510a75p-3, -0x1.6002455599e2fp-4, 0x1.7b096936192c4p-6,
-0x1.e5577187e8bf8p-9, 0x1.169ef81d6c34ep-12
};
double z = asdouble ((uint64_t) mant << 28 | UINT64_C(0x3ff) << 52);
double r0 = -0x1.9931c6c2d19d1p-6 / z;
double z2 = z * z;
double z4 = z2 * z2;
double f = ((c[0] + z * c[1]) + z2 * (c[2] + z * c[3]))
+ z4 * ((c[4] + z * c[5]) + z2 * (c[6] + z * c[7])) + r0;
double r = f * cvt2;
float ub = r;
float lb = r - cvt2 * 1.4182e-9;
if (__glibc_likely (ub == lb))
return ub;
const double u0 = -0x1.ab16ec65d138fp+3;
double h = f * f * f - z;
f -= (f * r0 * u0) * h;
r = f * cvt2;
uint64_t cvt1 = asuint64 (r);
ub = r;
int64_t m0 = cvt1 << 19;
int64_t m1 = m0 >> 63;
if (__glibc_unlikely ((m0 ^ m1) < (UINT64_C(1) << 31)))
{
cvt1 = (cvt1 + (UINT64_C(1) << 31)) & UINT64_C(0xffffffff00000000);
ub = asdouble (cvt1);
}
return ub;
} }
libm_alias_float (__cbrt, cbrt) libm_alias_float (__cbrt, cbrt)

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -379,22 +379,18 @@ ldouble: 1
Function: "cbrt": Function: "cbrt":
double: 1 double: 1
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 1 double: 1
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 1 double: 1
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 1 double: 1
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -81,7 +81,6 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 3 double: 3
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -333,19 +333,15 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -84,7 +84,6 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -333,19 +333,15 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -333,19 +333,15 @@ float: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -506,25 +506,21 @@ ldouble: 6
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
float128: 1 float128: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
float128: 1 float128: 1
ldouble: 5 ldouble: 5
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
float128: 1 float128: 1
ldouble: 3 ldouble: 3
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
float128: 2 float128: 2
ldouble: 2 ldouble: 2

View File

@ -421,22 +421,18 @@ ldouble: 6
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 5 ldouble: 5
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 3 ldouble: 3
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 2 ldouble: 2
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -164,11 +164,9 @@ float: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
Function: Real part of "ccos": Function: Real part of "ccos":
double: 1 double: 1

View File

@ -417,22 +417,18 @@ ldouble: 2
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
ldouble: 1 ldouble: 1
Function: Real part of "ccos": Function: Real part of "ccos":

View File

@ -638,25 +638,21 @@ ldouble: 1
Function: "cbrt": Function: "cbrt":
double: 4 double: 4
float: 1
float128: 1 float128: 1
ldouble: 1 ldouble: 1
Function: "cbrt_downward": Function: "cbrt_downward":
double: 4 double: 4
float: 1
float128: 1 float128: 1
ldouble: 1 ldouble: 1
Function: "cbrt_towardzero": Function: "cbrt_towardzero":
double: 3 double: 3
float: 1
float128: 1 float128: 1
ldouble: 1 ldouble: 1
Function: "cbrt_upward": Function: "cbrt_upward":
double: 5 double: 5
float: 1
float128: 1 float128: 1
ldouble: 1 ldouble: 1