Browse Source

core: improve sin() and exp() performance by replacing divisions with

multiplications where appropriate.
legacy
Sam Hocevar sam 13 years ago
parent
commit
4041166c56
2 changed files with 24 additions and 6 deletions
  1. +12
    -6
      src/real.cpp
  2. +12
    -0
      test/benchmark/real.cpp

+ 12
- 6
src/real.cpp View File

@@ -668,13 +668,16 @@ static real fast_exp(real const &x)

for (int i = 1; ; i++)
{
fact *= (real)i;
real newret = ret + xn / fact;
real newret = ret + xn;
if (newret == ret)
break;
ret = newret;
real mul = (i + 1);
fact *= mul;
ret *= mul;
xn *= x;
}
ret /= fact;

return ret;
}
@@ -802,16 +805,19 @@ real sin(real const &x)
if (absx > real::R_PI_2)
absx = real::R_PI - absx;

real ret = real::R_0, fact = real::R_1, xn = absx, x2 = absx * absx;
real ret = real::R_0, fact = real::R_1, xn = absx, mx2 = -absx * absx;
for (int i = 1; ; i += 2)
{
real newret = ret + xn / fact;
real newret = ret + xn;
if (newret == ret)
break;
ret = newret;
xn *= x2;
fact *= (real)(-(i + 1) * (i + 2));
real mul = (i + 1) * (i + 2);
fact *= mul;
ret *= mul;
xn *= mx2;
}
ret /= fact;

/* Propagate sign */
if (switch_sign)


+ 12
- 0
test/benchmark/real.cpp View File

@@ -56,6 +56,16 @@ void bench_real(int mode)
for (size_t i = 0; i < REAL_TABLE_SIZE; i++)
invfact = invfact / real(1.0 + i);
result[2] += timer.GetMs();

timer.GetMs();
for (size_t i = 0; i < REAL_TABLE_SIZE / 128; i++)
sin(real(0.01 * i));
result[3] += timer.GetMs() * 128;

timer.GetMs();
for (size_t i = 0; i < REAL_TABLE_SIZE / 128; i++)
exp((real)(int)(i - REAL_TABLE_SIZE / 256));
result[4] += timer.GetMs() * 128;
}

for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
@@ -65,5 +75,7 @@ void bench_real(int mode)
Log::Info("real = real + real %7.3f\n", result[0]);
Log::Info("real = real * real %7.3f\n", result[1]);
Log::Info("real = real / real %7.3f\n", result[2]);
Log::Info("real = sin(real) %7.3f\n", result[3]);
Log::Info("real = exp(real) %7.3f\n", result[4]);
}


Loading…
Cancel
Save