// 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); } static void SumSizes(::benchmark::Benchmark* b) { for (int n : {256, 1024, 4096, 16384, 65536, 262144, 1048576}) b->Arg(n); } static void GemvSizes(::benchmark::Benchmark* b) { for (int n : {32, 128, 512, 1024}) b->Arg(n); } BENCHMARK(BM_MapContiguousSum)->Apply(SumSizes)->Name("MapContiguousSum_float"); BENCHMARK(BM_MapStridedSum)->Apply(SumSizes)->Name("MapStridedSum_float"); BENCHMARK(BM_OwnedSum)->Apply(SumSizes)->Name("OwnedSum_float"); BENCHMARK(BM_MapContiguousSum)->Apply(SumSizes)->Name("MapContiguousSum_double"); BENCHMARK(BM_MapStridedSum)->Apply(SumSizes)->Name("MapStridedSum_double"); BENCHMARK(BM_OwnedSum)->Apply(SumSizes)->Name("OwnedSum_double"); BENCHMARK(BM_MapGemv)->Apply(GemvSizes)->Name("MapGemv_float"); BENCHMARK(BM_OwnedGemv)->Apply(GemvSizes)->Name("OwnedGemv_float"); BENCHMARK(BM_MapGemv)->Apply(GemvSizes)->Name("MapGemv_double"); BENCHMARK(BM_OwnedGemv)->Apply(GemvSizes)->Name("OwnedGemv_double");