// Benchmarks for Map and Ref with various strides. // // Compares contiguous Map vs strided Map vs owned matrix for basic // operations (GEMV and vector sum). #include #include using namespace Eigen; // Sum a contiguous Map. template static void BM_MapContiguousSum(benchmark::State& state) { const Index n = state.range(0); std::vector buf(n); Map> v(buf.data(), n); v.setRandom(); for (auto _ : state) { Scalar s = v.sum(); benchmark::DoNotOptimize(s); } state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar)); } // Sum a strided Map (InnerStride). template static void BM_MapStridedSum(benchmark::State& state) { const Index n = state.range(0); const Index stride = 3; std::vector buf(n * stride); Map, 0, InnerStride<>> v(buf.data(), n, InnerStride<>(stride)); v.setRandom(); for (auto _ : state) { Scalar s = v.sum(); benchmark::DoNotOptimize(s); } state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar)); } // Sum an owned VectorX (baseline). template static void BM_OwnedSum(benchmark::State& state) { const Index n = state.range(0); Matrix v = Matrix::Random(n); for (auto _ : state) { Scalar s = v.sum(); benchmark::DoNotOptimize(s); } state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar)); } // GEMV through contiguous Map. template static void BM_MapGemv(benchmark::State& state) { const Index n = state.range(0); std::vector buf(n * n); Map> A(buf.data(), n, n); A.setRandom(); Matrix x = Matrix::Random(n); Matrix y = Matrix::Random(n); for (auto _ : state) { y.noalias() += A * x; benchmark::DoNotOptimize(y.data()); benchmark::ClobberMemory(); } state.counters["GFLOPS"] = benchmark::Counter(2.0 * n * n, benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::kIs1000); } // GEMV with owned matrix (baseline). template static void BM_OwnedGemv(benchmark::State& state) { const Index n = state.range(0); Matrix A = Matrix::Random(n, n); Matrix x = Matrix::Random(n); Matrix y = Matrix::Random(n); for (auto _ : state) { y.noalias() += A * x; benchmark::DoNotOptimize(y.data()); benchmark::ClobberMemory(); } state.counters["GFLOPS"] = benchmark::Counter(2.0 * n * n, benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::kIs1000); } // clang-format off #define SUM_SIZES ->Arg(256)->Arg(1024)->Arg(4096)->Arg(16384)->Arg(65536)->Arg(262144)->Arg(1048576) BENCHMARK(BM_MapContiguousSum) SUM_SIZES ->Name("MapContiguousSum_float"); BENCHMARK(BM_MapStridedSum) SUM_SIZES ->Name("MapStridedSum_float"); BENCHMARK(BM_OwnedSum) SUM_SIZES ->Name("OwnedSum_float"); BENCHMARK(BM_MapContiguousSum) SUM_SIZES ->Name("MapContiguousSum_double"); BENCHMARK(BM_MapStridedSum) SUM_SIZES ->Name("MapStridedSum_double"); BENCHMARK(BM_OwnedSum) SUM_SIZES ->Name("OwnedSum_double"); #undef SUM_SIZES BENCHMARK(BM_MapGemv)->Arg(32)->Arg(128)->Arg(512)->Arg(1024)->Name("MapGemv_float"); BENCHMARK(BM_OwnedGemv)->Arg(32)->Arg(128)->Arg(512)->Arg(1024)->Name("OwnedGemv_float"); BENCHMARK(BM_MapGemv)->Arg(32)->Arg(128)->Arg(512)->Arg(1024)->Name("MapGemv_double"); BENCHMARK(BM_OwnedGemv)->Arg(32)->Arg(128)->Arg(512)->Arg(1024)->Name("OwnedGemv_double"); // clang-format on