blob: f49e9ca25d988c9073607d9b2b78c3c9aeb86883 [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include <benchmark/benchmark.h>
#include <Eigen/Core>
using namespace Eigen;
template <typename Scalar, int Stride>
EIGEN_DONT_INLINE void gather_packets(const Scalar* input, Scalar* output, Index size, Index runtime_stride) {
using Packet = typename internal::packet_traits<Scalar>::type;
constexpr Index PacketSize = internal::packet_traits<Scalar>::size;
const Index stride = Stride == Dynamic ? runtime_stride : Stride;
for (Index i = 0; i < size; i += PacketSize) {
internal::pstoreu(output + i, internal::pgather<Scalar, Packet>(input + i * stride, stride));
}
}
template <typename Scalar, int Stride>
static void BM_Pgather(benchmark::State& state) {
const Index size = state.range(0);
const Index stride = Stride == Dynamic ? state.range(1) : Stride;
Array<Scalar, Dynamic, 1> input((size - 1) * stride + 1), output(size);
for (Index i = 0; i < input.size(); ++i) input(i) = Scalar(i % 127);
gather_packets<Scalar, Stride>(input.data(), output.data(), size, stride);
for (Index i = 0; i < size; ++i) {
if (output(i) != input(i * stride)) {
state.SkipWithError("Incorrect gathered coefficient");
return;
}
}
for (auto _ : state) {
benchmark::ClobberMemory();
gather_packets<Scalar, Stride>(input.data(), output.data(), size, stride);
benchmark::DoNotOptimize(output.data());
}
state.SetItemsProcessed(state.iterations() * size);
}
template <typename Scalar>
EIGEN_DONT_INLINE void scatter_packets(const Scalar* input, Scalar* output, Index size, Index stride) {
using Packet = typename internal::packet_traits<Scalar>::type;
constexpr Index PacketSize = internal::packet_traits<Scalar>::size;
for (Index i = 0; i < size; i += PacketSize) {
internal::pscatter<Scalar, Packet>(output + i * stride, internal::ploadu<Packet>(input + i), stride);
}
}
template <typename Scalar>
static void BM_Pscatter(benchmark::State& state) {
Index size = state.range(0);
Index stride = state.range(1);
Array<Scalar, Dynamic, 1> input(size), output((size - 1) * stride + 1);
for (Index i = 0; i < size; ++i) input(i) = Scalar(i % 127);
scatter_packets(input.data(), output.data(), size, stride);
for (Index i = 0; i < size; ++i) {
if (output(i * stride) != input(i)) {
state.SkipWithError("Incorrect scattered coefficient");
return;
}
}
for (auto _ : state) {
benchmark::ClobberMemory();
scatter_packets(input.data(), output.data(), size, stride);
benchmark::DoNotOptimize(output.data());
}
state.SetItemsProcessed(state.iterations() * size);
}
BENCHMARK_TEMPLATE(BM_Pgather, float, 2)->Arg(64)->Arg(4096);
BENCHMARK_TEMPLATE(BM_Pgather, double, 2)->Arg(64)->Arg(4096);
BENCHMARK_TEMPLATE(BM_Pgather, float, Dynamic)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});
BENCHMARK_TEMPLATE(BM_Pgather, double, Dynamic)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});
BENCHMARK_TEMPLATE(BM_Pgather, std::complex<float>, Dynamic)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});
BENCHMARK_TEMPLATE(BM_Pgather, std::complex<double>, Dynamic)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});
BENCHMARK_TEMPLATE(BM_Pscatter, float)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});
BENCHMARK_TEMPLATE(BM_Pscatter, std::complex<float>)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});
BENCHMARK_TEMPLATE(BM_Pscatter, std::complex<double>)->ArgsProduct({{64, 4096}, {1, 2, 3, 7}});