| // 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() |