2026-02-22 12:19:37 -08:00
|
|
|
// Benchmarks for block extraction and assignment operations.
|
|
|
|
|
//
|
|
|
|
|
// Tests sub-matrix views: block(), topRows(), leftCols(), middleCols().
|
|
|
|
|
// Measures expression template overhead for read and write patterns.
|
|
|
|
|
|
|
|
|
|
#include <benchmark/benchmark.h>
|
|
|
|
|
#include <Eigen/Core>
|
|
|
|
|
|
|
|
|
|
using namespace Eigen;
|
|
|
|
|
|
|
|
|
|
// Read a block and assign to a separate matrix (forces evaluation).
|
|
|
|
|
template <typename Scalar>
|
|
|
|
|
static void BM_BlockRead(benchmark::State& state) {
|
|
|
|
|
const Index n = state.range(0);
|
|
|
|
|
const Index block_size = state.range(1);
|
|
|
|
|
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
|
|
|
|
|
Mat src = Mat::Random(n, n);
|
|
|
|
|
Mat dst(block_size, block_size);
|
|
|
|
|
const Index off = (n - block_size) / 2;
|
|
|
|
|
for (auto _ : state) {
|
|
|
|
|
dst = src.block(off, off, block_size, block_size);
|
|
|
|
|
benchmark::DoNotOptimize(dst.data());
|
|
|
|
|
}
|
|
|
|
|
state.SetBytesProcessed(state.iterations() * block_size * block_size * sizeof(Scalar));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write into a block of a larger matrix.
|
|
|
|
|
template <typename Scalar>
|
|
|
|
|
static void BM_BlockWrite(benchmark::State& state) {
|
|
|
|
|
const Index n = state.range(0);
|
|
|
|
|
const Index block_size = state.range(1);
|
|
|
|
|
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
|
|
|
|
|
Mat dst = Mat::Random(n, n);
|
|
|
|
|
Mat src = Mat::Random(block_size, block_size);
|
|
|
|
|
const Index off = (n - block_size) / 2;
|
|
|
|
|
for (auto _ : state) {
|
|
|
|
|
dst.block(off, off, block_size, block_size) = src;
|
|
|
|
|
benchmark::DoNotOptimize(dst.data());
|
|
|
|
|
}
|
|
|
|
|
state.SetBytesProcessed(state.iterations() * block_size * block_size * sizeof(Scalar));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// topRows extraction.
|
|
|
|
|
template <typename Scalar>
|
|
|
|
|
static void BM_TopRows(benchmark::State& state) {
|
|
|
|
|
const Index n = state.range(0);
|
|
|
|
|
const Index k = state.range(1);
|
|
|
|
|
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
|
|
|
|
|
Mat src = Mat::Random(n, n);
|
|
|
|
|
Mat dst(k, n);
|
|
|
|
|
for (auto _ : state) {
|
|
|
|
|
dst = src.topRows(k);
|
|
|
|
|
benchmark::DoNotOptimize(dst.data());
|
|
|
|
|
}
|
|
|
|
|
state.SetBytesProcessed(state.iterations() * k * n * sizeof(Scalar));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// leftCols extraction.
|
|
|
|
|
template <typename Scalar>
|
|
|
|
|
static void BM_LeftCols(benchmark::State& state) {
|
|
|
|
|
const Index n = state.range(0);
|
|
|
|
|
const Index k = state.range(1);
|
|
|
|
|
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
|
|
|
|
|
Mat src = Mat::Random(n, n);
|
|
|
|
|
Mat dst(n, k);
|
|
|
|
|
for (auto _ : state) {
|
|
|
|
|
dst = src.leftCols(k);
|
|
|
|
|
benchmark::DoNotOptimize(dst.data());
|
|
|
|
|
}
|
|
|
|
|
state.SetBytesProcessed(state.iterations() * n * k * sizeof(Scalar));
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 17:42:07 -07:00
|
|
|
// (matrix_size, block_size)
|
|
|
|
|
// clang-format off
|
|
|
|
|
#define BLOCK_SIZES ->ArgsProduct({{256, 512, 1024}, {16, 64, 128}})
|
|
|
|
|
BENCHMARK(BM_BlockRead<float>) BLOCK_SIZES ->Name("BlockRead_float");
|
|
|
|
|
BENCHMARK(BM_BlockRead<double>) BLOCK_SIZES ->Name("BlockRead_double");
|
|
|
|
|
BENCHMARK(BM_BlockWrite<float>) BLOCK_SIZES ->Name("BlockWrite_float");
|
|
|
|
|
BENCHMARK(BM_BlockWrite<double>) BLOCK_SIZES ->Name("BlockWrite_double");
|
|
|
|
|
BENCHMARK(BM_TopRows<float>) BLOCK_SIZES ->Name("TopRows_float");
|
|
|
|
|
BENCHMARK(BM_TopRows<double>) BLOCK_SIZES ->Name("TopRows_double");
|
|
|
|
|
BENCHMARK(BM_LeftCols<float>) BLOCK_SIZES ->Name("LeftCols_float");
|
|
|
|
|
BENCHMARK(BM_LeftCols<double>) BLOCK_SIZES ->Name("LeftCols_double");
|
|
|
|
|
#undef BLOCK_SIZES
|
|
|
|
|
// clang-format on
|