Files
filament/libs/math/benchmarks/benchmark_fast.cpp
Mathias Agopian 6d68a4a4c6 libmath benchmarks
2018-12-03 11:58:30 -08:00

156 lines
4.6 KiB
C++

/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "PerformanceCounters.h"
#include <benchmark/benchmark.h>
#include <math/fast.h>
#include <cmath>
using namespace math;
template <typename T>
static void BM_trig(benchmark::State& state) {
T f;
state.SetLabel(T::label());
std::vector<float> data(1024);
for (size_t i = 0; i < data.size(); i++) {
data[i] = float((float(i) / data.size()) * M_2_PI - M_PI);
}
{
PerformanceCounters pc(state);
for (auto _ : state) {
#pragma unroll(16)
for (float v : data) {
benchmark::DoNotOptimize(f(v));
}
}
state.SetItemsProcessed(state.iterations() * data.size());
}
}
template <typename T>
static void BM_func(benchmark::State& state) {
T f;
state.SetLabel(T::label());
std::vector<float> data(1024);
std::vector<float> res(1024);
for (size_t i = 0; i < data.size(); i++) {
data[i] = (float(i + 1) / (data.size() + 1)) * 1024;
}
{
PerformanceCounters pc(state);
for (auto _ : state) {
#pragma unroll(16)
for (size_t i = 0, c = data.size(); i < c; i++) {
res[i] = f(data[i]);
benchmark::DoNotOptimize(res[i]);
}
benchmark::ClobberMemory();
}
state.SetItemsProcessed(state.iterations() * data.size());
}
}
template <typename T>
static void BM_func_smp(benchmark::State& state) {
T f;
state.SetLabel(T::label());
std::vector<float> data(1024);
std::vector<float> res(1024);
for (size_t i = 0; i < data.size(); i++) {
data[i] = (float(i + 1) / (data.size() + 1)) * 1024;
}
{
PerformanceCounters pc(state);
for (auto _ : state) {
#pragma loop vectorize_width(4)
for (size_t i = 0, c = data.size(); i < c; i++) {
res[i] = f(data[i]);
}
benchmark::ClobberMemory();
benchmark::DoNotOptimize(res);
}
state.SetItemsProcessed(state.iterations() * data.size());
}
}
struct StdCos {
float operator()(float v) { return std::cos(v); }
static const char* label() { return "std::cos"; }
};
struct FastCos {
float operator()(float v) { return fast::cos(v); }
static const char* label() { return "fast::cos"; }
};
struct StdLog2 {
float operator()(float v) { return std::log2(v); }
static const char* label() { return "std::log2"; }
};
struct FastLog2 {
float operator()(float v) { return fast::log2(v); }
static const char* label() { return "fast::log2"; }
};
struct Rcp {
float operator()(float v) { return 1.0f/v; }
static const char* label() { return "1/x"; }
};
struct StdISqrt {
float operator()(float v) { return 1.0f / std::sqrt(v); }
static const char* label() { return "1/std::sqrt"; }
};
struct FastISqrt {
float operator()(float v) { return fast::isqrt(v); }
static const char* label() { return "fast::isqrt"; }
};
struct StdPow2dot2 {
float operator()(float v) { return std::pow(v, 2.2f); }
static const char* label() { return "std::pow(x, 2.2f)"; }
};
struct StdExp2dot2Log {
float operator()(float v) { return std::exp(2.2f * std::log(v)); }
static const char* label() { return "std::exp(2.2f * std::log(x))"; }
};
struct FastPow2dot2 {
float operator()(float v) { return fast::pow2dot2(v); }
static const char* label() { return "fast::pow2dot2"; }
};
BENCHMARK_TEMPLATE(BM_trig, StdCos);
BENCHMARK_TEMPLATE(BM_trig, FastCos);
BENCHMARK_TEMPLATE(BM_func, StdLog2);
BENCHMARK_TEMPLATE(BM_func, FastLog2);
BENCHMARK_TEMPLATE(BM_func_smp, FastLog2);
BENCHMARK_TEMPLATE(BM_func, Rcp);
BENCHMARK_TEMPLATE(BM_func_smp, Rcp);
BENCHMARK_TEMPLATE(BM_func, StdISqrt);
BENCHMARK_TEMPLATE(BM_func_smp, StdISqrt);
BENCHMARK_TEMPLATE(BM_func, FastISqrt);
BENCHMARK_TEMPLATE(BM_func_smp, FastISqrt);
BENCHMARK_TEMPLATE(BM_func, StdPow2dot2);
BENCHMARK_TEMPLATE(BM_func, StdExp2dot2Log);
BENCHMARK_TEMPLATE(BM_func_smp, StdExp2dot2Log);
BENCHMARK_TEMPLATE(BM_func, FastPow2dot2);
BENCHMARK_TEMPLATE(BM_func_smp, FastPow2dot2);