blob: 2ba8f49dd568f4000f8d8187b187f3de7ed49637 [file] [edit]
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
// Launch overhead: the cost of evaluating a tiny expression through the Tensor executor (one element and one
// packet-sized block), against a raw <<<>>> launch of an empty kernel, the same launch through LAUNCH_GPU_KERNEL
// (which adds a cudaGetLastError) and cudaLaunchKernel. 1000 launches per iteration; the device time per launch is
// the reported time, the host time per enqueue is the host_us_per_launch counter.
#include "gpu_bench_common.h"
namespace {
using eigen_bench::DeviceBuffer;
const int kLaunchesPerIteration = 1000;
const int kIterations = 20;
const std::vector<int64_t> kSizes = {1, 1024};
template <int MapOptions>
void BM_ExecutorAssign(benchmark::State& state) {
const int64_t n = state.range(0);
DeviceBuffer<float> a(n), out(n);
a.fillRandom();
Eigen::GpuStreamDevice stream;
Eigen::GpuDevice device(&stream);
Eigen::TensorMap<Eigen::Tensor<float, 1>, MapOptions> ta(a.data(), n), tout(out.data(), n);
const auto enqueue = [&] { tout.device(device) = ta; };
eigen_bench::warmUp(device.stream(), enqueue);
eigen_bench::requireClose(out.toHost(), a.toHost(), 0.0, "assign");
eigen_bench::timeLaunches(state, device.stream(), enqueue, kLaunchesPerIteration);
}
__global__ void noop_kernel(int) {}
void BM_RawLaunch(benchmark::State& state) {
cudaStream_t stream = nullptr;
const auto enqueue = [&] { noop_kernel<<<1, 32, 0, stream>>>(0); };
eigen_bench::warmUp(stream, enqueue);
eigen_bench::timeLaunches(state, stream, enqueue, kLaunchesPerIteration);
}
void BM_CheckedLaunch(benchmark::State& state) {
Eigen::GpuStreamDevice stream;
Eigen::GpuDevice device(&stream);
const auto enqueue = [&] { LAUNCH_GPU_KERNEL(noop_kernel, 1, 32, 0, device, 0); };
eigen_bench::warmUp(device.stream(), enqueue);
eigen_bench::timeLaunches(state, device.stream(), enqueue, kLaunchesPerIteration);
}
void BM_CudaLaunchKernel(benchmark::State& state) {
cudaStream_t stream = nullptr;
int arg = 0;
void* args[] = {&arg};
const auto enqueue = [&] {
EIGEN_GPU_RUNTIME_CHECK(
cudaLaunchKernel(reinterpret_cast<const void*>(&noop_kernel), dim3(1), dim3(32), args, 0, stream));
};
eigen_bench::warmUp(stream, enqueue);
eigen_bench::timeLaunches(state, stream, enqueue, kLaunchesPerIteration);
}
} // namespace
EIGEN_GPU_BENCHMARK_SIZES(BM_ExecutorAssign, Eigen::Aligned);
EIGEN_GPU_BENCHMARK_SIZES(BM_ExecutorAssign, Eigen::Unaligned);
EIGEN_GPU_BENCHMARK(BM_RawLaunch);
EIGEN_GPU_BENCHMARK(BM_CheckedLaunch);
EIGEN_GPU_BENCHMARK(BM_CudaLaunchKernel);
EIGEN_GPU_BENCHMARK_MAIN()