Speed up pexp_double by ~15-17%

libeigen/eigen!2388

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-04-03 17:09:11 -07:00
parent a91913e961
commit a3074053a6

View File

@@ -466,7 +466,6 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp_double(const Pac
const Packet cst_zero = pset1<Packet>(0.0); const Packet cst_zero = pset1<Packet>(0.0);
const Packet cst_1 = pset1<Packet>(1.0); const Packet cst_1 = pset1<Packet>(1.0);
const Packet cst_2 = pset1<Packet>(2.0); const Packet cst_2 = pset1<Packet>(2.0);
const Packet cst_half = pset1<Packet>(0.5);
const Packet cst_exp_hi = pset1<Packet>(709.784); const Packet cst_exp_hi = pset1<Packet>(709.784);
const Packet cst_exp_lo = pset1<Packet>(-745.519); const Packet cst_exp_lo = pset1<Packet>(-745.519);
@@ -482,25 +481,19 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp_double(const Pac
const Packet cst_cephes_exp_C1 = pset1<Packet>(0.693145751953125); const Packet cst_cephes_exp_C1 = pset1<Packet>(0.693145751953125);
const Packet cst_cephes_exp_C2 = pset1<Packet>(1.42860682030941723212e-6); const Packet cst_cephes_exp_C2 = pset1<Packet>(1.42860682030941723212e-6);
Packet tmp, fx; // Clamp x.
// clamp x
Packet zero_mask = pcmp_lt(_x, cst_exp_lo); Packet zero_mask = pcmp_lt(_x, cst_exp_lo);
Packet x = pmin(_x, cst_exp_hi); Packet x = pmin(_x, cst_exp_hi);
// Express exp(x) as exp(g + n*log(2)). // Express exp(x) as exp(g + n*log(2)).
fx = pmadd(cst_cephes_LOG2EF, x, cst_half); // n = rint(x / ln(2)).
Packet fx = print(pmul(x, cst_cephes_LOG2EF));
// Get the integer modulus of log(2), i.e. the "n" described above.
fx = pfloor(fx);
// Get the remainder modulo log(2), i.e. the "g" described above. Subtract // Get the remainder modulo log(2), i.e. the "g" described above. Subtract
// n*log(2) out in two steps, i.e. n*C1 + n*C2, C1+C2=log2 to get the last // n*log(2) out in two steps, i.e. n*C1 + n*C2, C1+C2=log2 to get the last
// digits right. // digits right.
tmp = pmul(fx, cst_cephes_exp_C1); x = pnmadd(fx, cst_cephes_exp_C1, x);
Packet z = pmul(fx, cst_cephes_exp_C2); x = pnmadd(fx, cst_cephes_exp_C2, x);
x = psub(x, tmp);
x = psub(x, z);
Packet x2 = pmul(x, x); Packet x2 = pmul(x, x);
@@ -516,9 +509,7 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp_double(const Pac
qx = pmadd(qx, x2, cst_cephes_exp_q2); qx = pmadd(qx, x2, cst_cephes_exp_q2);
qx = pmadd(qx, x2, cst_cephes_exp_q3); qx = pmadd(qx, x2, cst_cephes_exp_q3);
// I don't really get this bit, copied from the SSE2 routines, so... // exp(g) = 1 + 2*px/(qx - px).
// TODO(gonnet): Figure out what is going on here, perhaps find a better
// rational interpolant?
x = pdiv(px, psub(qx, px)); x = pdiv(px, psub(qx, px));
x = pmadd(cst_2, x, cst_1); x = pmadd(cst_2, x, cst_1);