blob: ec4464c38590985154626e9ac2c5a67f95de3dca [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include <benchmark/benchmark.h>
#include <Eigen/Core>
#include <algorithm>
#include <numeric>
template <int Stride, bool Reverse>
static void BM_StridedIterator(benchmark::State& state) {
const Eigen::Index size = state.range(0);
const Eigen::Index stride = state.range(1);
// Padding also makes the pre-fix iterator's end pointer valid for the comparison build.
Eigen::VectorXd storage(size * Eigen::numext::abs(stride) + 1);
Eigen::Map<Eigen::VectorXd, Eigen::Unaligned, Eigen::InnerStride<Stride>> values(
storage.data() + (stride < 0 ? storage.size() - 1 : 0), size, Eigen::InnerStride<Stride>(stride));
for (Eigen::Index i = 0; i < size; ++i) values[i] = double(i + 1);
const double expected = double(size) * double(size + 1) / 2;
if (std::accumulate(values.begin(), values.end(), 0.0) != expected) {
state.SkipWithError("Incorrect iterator sum");
return;
}
for (auto _ : state) {
benchmark::ClobberMemory();
EIGEN_IF_CONSTEXPR (Reverse) {
std::reverse(values.begin(), values.end());
benchmark::DoNotOptimize(values.data());
} else {
double sum = std::accumulate(values.begin(), values.end(), 0.0);
benchmark::DoNotOptimize(sum);
}
}
const bool reversed = Reverse && state.iterations() % 2 != 0;
for (Eigen::Index i = 0; i < size; ++i) {
if (values[i] != double(reversed ? size - i : i + 1)) {
state.SkipWithError("Incorrect iterator traversal");
return;
}
}
state.SetItemsProcessed(state.iterations() * size);
}
BENCHMARK_TEMPLATE(BM_StridedIterator, 1, false)->ArgsProduct({{16, 256, 4096}, {1}});
BENCHMARK_TEMPLATE(BM_StridedIterator, 2, false)->ArgsProduct({{16, 256, 4096}, {2}});
BENCHMARK_TEMPLATE(BM_StridedIterator, Eigen::Dynamic, false)->ArgsProduct({{16, 256, 4096}, {-2, 1, 2}});
BENCHMARK_TEMPLATE(BM_StridedIterator, 1, true)->ArgsProduct({{16, 256, 4096}, {1}});
BENCHMARK_TEMPLATE(BM_StridedIterator, 2, true)->ArgsProduct({{16, 256, 4096}, {2}});
BENCHMARK_TEMPLATE(BM_StridedIterator, Eigen::Dynamic, true)->ArgsProduct({{16, 256, 4096}, {-2, 1, 2}});