Skip to content

Commit

Permalink
More benchmarks work
Browse files Browse the repository at this point in the history
  • Loading branch information
jatinchowdhury18 committed Nov 23, 2023
1 parent f0ca995 commit efcf6ad
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 23 deletions.
38 changes: 34 additions & 4 deletions include/math_approx/src/log_approx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ namespace log_detail
template <typename Base, int order>
float log (float x)
{
const auto vi = reinterpret_cast<int32_t&> (x); // NOSONAR
const auto vi = reinterpret_cast<int32_t&> (x);
const auto ex = vi & 0x7f800000;
const auto e = (ex >> 23) - 127;
const auto vfi = (vi - ex) | 0x3f800000;
const auto vf = reinterpret_cast<const float&> (vfi); // NOSONAR
const auto vf = reinterpret_cast<const float&> (vfi);

static constexpr auto log2_base_r = 1.0f / Base::log2_base;
return log2_base_r * ((float) e + log_detail::log2_approx<float, order> (vf));
Expand All @@ -70,16 +70,46 @@ float log (float x)
template <typename Base, int order>
double log (double x)
{
const auto vi = reinterpret_cast<int64_t&> (x); // NOSONAR
const auto vi = reinterpret_cast<int64_t&> (x);
const auto ex = vi & 0x7ff0000000000000;
const auto e = (ex >> 52) - 1023;
const auto vfi = (vi - ex) | 0x3ff0000000000000;
const auto vf = reinterpret_cast<const double&> (vfi); // NOSONAR
const auto vf = reinterpret_cast<const double&> (vfi);

static constexpr auto log2_base_r = 1.0 / Base::log2_base;
return log2_base_r * ((double) e + log_detail::log2_approx<double, order> (vf));
}

#if defined(XSIMD_HPP)
/** approximation for pow(Base, x) (32-bit SIMD) */
template <typename Base, int order>
xsimd::batch<float> log (xsimd::batch<float> x)
{
const auto vi = reinterpret_cast<int32_t&> (x);
const auto ex = vi & 0x7f800000;
const auto e = (ex >> 23) - 127;
const auto vfi = (vi - ex) | 0x3f800000;
const auto vf = reinterpret_cast<const float&> (vfi);

static constexpr auto log2_base_r = 1.0f / Base::log2_base;
return log2_base_r * ((float) e + log_detail::log2_approx<xsimd::batch<float>, order> (vf));
}

/** approximation for pow(Base, x) (64-bit SIMD) */
template <typename Base, int order>
xsimd::batch<double> log (xsimd::batch<double> x)
{
const auto vi = reinterpret_cast<int64_t&> (x);
const auto ex = vi & 0x7ff0000000000000;
const auto e = (ex >> 52) - 1023;
const auto vfi = (vi - ex) | 0x3ff0000000000000;
const auto vf = reinterpret_cast<const double&> (vfi);

static constexpr auto log2_base_r = 1.0 / Base::log2_base;
return log2_base_r * ((double) e + log_detail::log2_approx<xsimd::batch<double>, order> (vf));
}
#endif

template <int order, typename T>
T log (T x)
{
Expand Down
30 changes: 30 additions & 0 deletions include/math_approx/src/pow_approx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,36 @@ double pow (double x)
return reinterpret_cast<const double&> (vi) * pow_detail::pow2_approx<double, order> (d);
}

#if defined(XSIMD_HPP)
/** approximation for pow(Base, x) (32-bit SIMD) */
template <typename Base, int order>
xsimd::batch<float> pow (xsimd::batch<float> x)
{
x = xsimd::max (xsimd::broadcast (-126.0f), Base::log2_base * x);

const auto xi = xsimd::to_int (x);
const auto l = xsimd::select (xsimd::batch_bool_cast<int32_t> (x < 0.0f), xi - 1, xi);
const auto f = x - xsimd::to_float (l);
const auto vi = (l + 127) << 23;

return reinterpret_cast<const xsimd::batch<float>&> (vi) * pow_detail::pow2_approx<xsimd::batch<float>, order> (f);
}

/** approximation for pow(Base, x) (64-bit SIMD) */
template <typename Base, int order>
xsimd::batch<double> pow (xsimd::batch<double> x)
{
x = xsimd::max (-1022.0, Base::log2_base * x);

const auto xi = xsimd::to_int (x);
const auto l = xsimd::select (xsimd::batch_bool_cast<int64_t> (x < 0.0), xi - 1, xi);
const auto d = x - xsimd::to_float (l);
const auto vi = (l + 1023) << 52;

return reinterpret_cast<const xsimd::batch<double>&> (vi) * pow_detail::pow2_approx<xsimd::batch<double>, order> (d);
}
#endif

template <int order, typename T>
T exp (T x)
{
Expand Down
3 changes: 3 additions & 0 deletions tools/bench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ target_link_libraries(trig_approx_bench PRIVATE benchmark::benchmark math_approx

add_executable(pow_approx_bench pow_bench.cpp)
target_link_libraries(pow_approx_bench PRIVATE benchmark::benchmark math_approx)

add_executable(log_approx_bench log_bench.cpp)
target_link_libraries(log_approx_bench PRIVATE benchmark::benchmark math_approx)
77 changes: 77 additions & 0 deletions tools/bench/log_bench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <math_approx/math_approx.hpp>
#include <benchmark/benchmark.h>

static constexpr size_t N = 2000;
const auto data = []
{
std::vector<float> x;
x.resize (N, 0.0f);
for (size_t i = 0; i < N; ++i)
x[i] = -10.0f + 20.0f * (float) i / (float) N;
return x;
}();

#define LOG_BENCH(name, func) \
void name (benchmark::State& state) \
{ \
for (auto _ : state) \
{ \
for (auto& x : data) \
{ \
auto y = func (x); \
benchmark::DoNotOptimize (y); \
} \
} \
} \
BENCHMARK (name);
LOG_BENCH (log_std, std::log)
LOG_BENCH (log_approx6, math_approx::log<6>)
LOG_BENCH (log_approx5, math_approx::log<5>)
LOG_BENCH (log_approx4, math_approx::log<4>)
LOG_BENCH (log_approx3, math_approx::log<3>)

LOG_BENCH (log2_std, std::log2)
LOG_BENCH (log2_approx6, math_approx::log2<6>)
LOG_BENCH (log2_approx5, math_approx::log2<5>)
LOG_BENCH (log2_approx4, math_approx::log2<4>)
LOG_BENCH (log2_approx3, math_approx::log2<3>)

LOG_BENCH (log10_std, std::log10)
LOG_BENCH (log10_approx6, math_approx::log10<6>)
LOG_BENCH (log10_approx5, math_approx::log10<5>)
LOG_BENCH (log10_approx4, math_approx::log10<4>)
LOG_BENCH (log10_approx3, math_approx::log10<3>)

#define LOG_SIMD_BENCH(name, func) \
void name (benchmark::State& state) \
{ \
for (auto _ : state) \
{ \
for (auto& x : data) \
{ \
auto y = func (xsimd::broadcast (x)); \
static_assert (std::is_same_v<xsimd::batch<float>, decltype(y)>); \
benchmark::DoNotOptimize (y); \
} \
} \
} \
BENCHMARK (name);
LOG_SIMD_BENCH (log_xsimd, xsimd::log)
LOG_SIMD_BENCH (log_simd_approx6, math_approx::log<6>)
LOG_SIMD_BENCH (log_simd_approx5, math_approx::log<5>)
LOG_SIMD_BENCH (log_simd_approx4, math_approx::log<4>)
LOG_SIMD_BENCH (log_simd_approx3, math_approx::log<3>)

LOG_SIMD_BENCH (log2_xsimd, xsimd::log2)
LOG_SIMD_BENCH (log2_simd_approx6, math_approx::log2<6>)
LOG_SIMD_BENCH (log2_simd_approx5, math_approx::log2<5>)
LOG_SIMD_BENCH (log2_simd_approx4, math_approx::log2<4>)
LOG_SIMD_BENCH (log2_simd_approx3, math_approx::log2<3>)

LOG_SIMD_BENCH (log10_xsimd, xsimd::log10)
LOG_SIMD_BENCH (log10_simd_approx6, math_approx::log10<6>)
LOG_SIMD_BENCH (log10_simd_approx5, math_approx::log10<5>)
LOG_SIMD_BENCH (log10_simd_approx4, math_approx::log10<4>)
LOG_SIMD_BENCH (log10_simd_approx3, math_approx::log10<3>)

BENCHMARK_MAIN();
66 changes: 47 additions & 19 deletions tools/bench/pow_bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,52 @@ POW_BENCH (exp_approx5, math_approx::exp<5>)
POW_BENCH (exp_approx4, math_approx::exp<4>)
POW_BENCH (exp_approx3, math_approx::exp<3>)

// #define POW_SIMD_BENCH(name, func) \
// void name (benchmark::State& state) \
// { \
// for (auto _ : state) \
// { \
// for (auto& x : data) \
// { \
// auto y = func (xsimd::broadcast (x)); \
// static_assert (std::is_same_v<xsimd::batch<float>, decltype(y)>); \
// benchmark::DoNotOptimize (y); \
// } \
// } \
// } \
// BENCHMARK (name);
// POW_SIMD_BENCH (exp_xsimd, xsimd::exp)
// POW_SIMD_BENCH (exp_simd_approx6, math_approx::exp<6>)
// POW_SIMD_BENCH (exp_simd_approx5, math_approx::exp<5>)
// POW_SIMD_BENCH (exp_simd_approx4, math_approx::exp<4>)
// POW_SIMD_BENCH (exp_simd_approx3, math_approx::exp<3>)
POW_BENCH (exp2_std, std::exp2)
POW_BENCH (exp2_approx6, math_approx::exp2<6>)
POW_BENCH (exp2_approx5, math_approx::exp2<5>)
POW_BENCH (exp2_approx4, math_approx::exp2<4>)
POW_BENCH (exp2_approx3, math_approx::exp2<3>)

float stdpow_exp10 (float x)
{
return std::pow (10.0f, x);
}
POW_BENCH (exp10_std, stdpow_exp10)
POW_BENCH (exp10_approx6, math_approx::exp10<6>)
POW_BENCH (exp10_approx5, math_approx::exp10<5>)
POW_BENCH (exp10_approx4, math_approx::exp10<4>)
POW_BENCH (exp10_approx3, math_approx::exp10<3>)

#define POW_SIMD_BENCH(name, func) \
void name (benchmark::State& state) \
{ \
for (auto _ : state) \
{ \
for (auto& x : data) \
{ \
auto y = func (xsimd::broadcast (x)); \
static_assert (std::is_same_v<xsimd::batch<float>, decltype(y)>); \
benchmark::DoNotOptimize (y); \
} \
} \
} \
BENCHMARK (name);
POW_SIMD_BENCH (exp_xsimd, xsimd::exp)
POW_SIMD_BENCH (exp_simd_approx6, math_approx::exp<6>)
POW_SIMD_BENCH (exp_simd_approx5, math_approx::exp<5>)
POW_SIMD_BENCH (exp_simd_approx4, math_approx::exp<4>)
POW_SIMD_BENCH (exp_simd_approx3, math_approx::exp<3>)

POW_SIMD_BENCH (exp2_xsimd, xsimd::exp2)
POW_SIMD_BENCH (exp2_simd_approx6, math_approx::exp2<6>)
POW_SIMD_BENCH (exp2_simd_approx5, math_approx::exp2<5>)
POW_SIMD_BENCH (exp2_simd_approx4, math_approx::exp2<4>)
POW_SIMD_BENCH (exp2_simd_approx3, math_approx::exp2<3>)

POW_SIMD_BENCH (exp10_xsimd, xsimd::exp10)
POW_SIMD_BENCH (exp10_simd_approx6, math_approx::exp10<6>)
POW_SIMD_BENCH (exp10_simd_approx5, math_approx::exp10<5>)
POW_SIMD_BENCH (exp10_simd_approx4, math_approx::exp10<4>)
POW_SIMD_BENCH (exp10_simd_approx3, math_approx::exp10<3>)

BENCHMARK_MAIN();

0 comments on commit efcf6ad

Please sign in to comment.