Files
eigen/benchmarks/Core/bench_reductions.cpp
2026-03-20 17:42:07 -07:00

174 lines
6.3 KiB
C++

// Benchmarks for full reductions: sum, prod, minCoeff, maxCoeff, mean,
// norm, squaredNorm, lpNorm<1>, lpNorm<Infinity>.
//
// These are memory-bandwidth-bound for large vectors, so we report
// bytes processed rather than FLOPS.
#include <benchmark/benchmark.h>
#include <Eigen/Core>
using namespace Eigen;
// --- Vector reductions (1-D) ---
template <typename Scalar>
static void BM_VectorSum(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar s = v.sum();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorProd(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Constant(n, Scalar(1));
// Use values near 1 to avoid overflow/underflow.
v += Scalar(0.001) * Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar p = v.prod();
benchmark::DoNotOptimize(p);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorMinCoeff(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar m = v.minCoeff();
benchmark::DoNotOptimize(m);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorMaxCoeff(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar m = v.maxCoeff();
benchmark::DoNotOptimize(m);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorMean(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar m = v.mean();
benchmark::DoNotOptimize(m);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorSquaredNorm(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar s = v.squaredNorm();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorNorm(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar s = v.norm();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorLpNorm1(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar s = v.template lpNorm<1>();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_VectorLpNormInf(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, 1> v = Matrix<Scalar, Dynamic, 1>::Random(n);
for (auto _ : state) {
Scalar s = v.template lpNorm<Infinity>();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar));
}
// --- Matrix reductions (2-D) ---
template <typename Scalar>
static void BM_MatrixSum(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, Dynamic> m = Matrix<Scalar, Dynamic, Dynamic>::Random(n, n);
for (auto _ : state) {
Scalar s = m.sum();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * n * sizeof(Scalar));
}
template <typename Scalar>
static void BM_MatrixNorm(benchmark::State& state) {
const Index n = state.range(0);
Matrix<Scalar, Dynamic, Dynamic> m = Matrix<Scalar, Dynamic, Dynamic>::Random(n, n);
for (auto _ : state) {
Scalar s = m.norm();
benchmark::DoNotOptimize(s);
}
state.SetBytesProcessed(state.iterations() * n * n * sizeof(Scalar));
}
// --- Size configurations ---
// clang-format off
#define VECTOR_SIZES ->Arg(64)->Arg(256)->Arg(1024)->Arg(4096)->Arg(16384)->Arg(65536)->Arg(262144)->Arg(1048576)
#define MATRIX_SIZES ->Arg(8)->Arg(32)->Arg(64)->Arg(128)->Arg(256)->Arg(512)->Arg(1024)
// --- Register: float ---
BENCHMARK(BM_VectorSum<float>) VECTOR_SIZES ->Name("VectorSum_float");
BENCHMARK(BM_VectorProd<float>) VECTOR_SIZES ->Name("VectorProd_float");
BENCHMARK(BM_VectorMinCoeff<float>) VECTOR_SIZES ->Name("VectorMinCoeff_float");
BENCHMARK(BM_VectorMaxCoeff<float>) VECTOR_SIZES ->Name("VectorMaxCoeff_float");
BENCHMARK(BM_VectorMean<float>) VECTOR_SIZES ->Name("VectorMean_float");
BENCHMARK(BM_VectorSquaredNorm<float>) VECTOR_SIZES ->Name("VectorSquaredNorm_float");
BENCHMARK(BM_VectorNorm<float>) VECTOR_SIZES ->Name("VectorNorm_float");
BENCHMARK(BM_VectorLpNorm1<float>) VECTOR_SIZES ->Name("VectorLpNorm1_float");
BENCHMARK(BM_VectorLpNormInf<float>) VECTOR_SIZES ->Name("VectorLpNormInf_float");
BENCHMARK(BM_MatrixSum<float>) MATRIX_SIZES ->Name("MatrixSum_float");
BENCHMARK(BM_MatrixNorm<float>) MATRIX_SIZES ->Name("MatrixNorm_float");
// --- Register: double ---
BENCHMARK(BM_VectorSum<double>) VECTOR_SIZES ->Name("VectorSum_double");
BENCHMARK(BM_VectorProd<double>) VECTOR_SIZES ->Name("VectorProd_double");
BENCHMARK(BM_VectorMinCoeff<double>) VECTOR_SIZES ->Name("VectorMinCoeff_double");
BENCHMARK(BM_VectorMaxCoeff<double>) VECTOR_SIZES ->Name("VectorMaxCoeff_double");
BENCHMARK(BM_VectorMean<double>) VECTOR_SIZES ->Name("VectorMean_double");
BENCHMARK(BM_VectorSquaredNorm<double>) VECTOR_SIZES ->Name("VectorSquaredNorm_double");
BENCHMARK(BM_VectorNorm<double>) VECTOR_SIZES ->Name("VectorNorm_double");
BENCHMARK(BM_VectorLpNorm1<double>) VECTOR_SIZES ->Name("VectorLpNorm1_double");
BENCHMARK(BM_VectorLpNormInf<double>) VECTOR_SIZES ->Name("VectorLpNormInf_double");
BENCHMARK(BM_MatrixSum<double>) MATRIX_SIZES ->Name("MatrixSum_double");
BENCHMARK(BM_MatrixNorm<double>) MATRIX_SIZES ->Name("MatrixNorm_double");
#undef VECTOR_SIZES
#undef MATRIX_SIZES
// clang-format on