谷歌基准测试库:BENCHMARK_TEMPLATE语法

7

我想在 floatdoublelong double 上运行 google/benchmark。

鉴于 BENCHMARK_TEMPLATE示例,我尝试了以下操作:

#include <cmath>
#include <ostream>
#include <random>
#include <benchmark/benchmark.h>

template<typename Real>
BM_PowTemplated(benchmark::State& state) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<Real> dis(1, 10);
    auto s = dis(gen);
    auto t = dis(gen);
    Real y;
    while (state.KeepRunning()) {
        benchmark::DoNotOptimize(y = std::pow(s, t));
    }
    std::ostream cnull(0);
    cnull << y;
}

BENCHMARK_TEMPLATE(BM_PowTemplated, float, double, long double);
BENCHMARK_MAIN();

我想创建三个浮点型的基准测试,分别为float,double和long double,但实际上它无法编译!创建模板化的 Google 基准测试的正确语法是什么?我的对于 BENCHMARK_TEMPLATE 如何使用的心理模型是正确的吗?如果是,我该如何修复这段代码?
1个回答

8
您以错误的方式使用了BENCHMARK_TEMPLATE和您的。

BENCHMARK_TEMPLATE(BM_PowTemplated, float, double, long double);

https://github.com/google/benchmark/ 的自述文件说:

template <class Q> int BM_Sequential(benchmark::State& state) { .. }
BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);

Three macros are provided for adding benchmark templates.

#define BENCHMARK_TEMPLATE(func, ...) // Takes any number of parameters.

#define BENCHMARK_TEMPLATE1(func, arg1)
#define BENCHMARK_TEMPLATE2(func, arg1, arg2)

因此,对于具有一个模板参数的函数,使用带有arg1的BENCHMARK_TEMPLATE,对于具有两个模板参数的函数,使用带有arg1和arg2的BENCHMARK_TEMPLATE。由于您的BM_PowTemplated只有一个参数,因此无法使用带有3个参数的BENCHMARK_TEMPLATE

请查看google/benchmark的test/cxx03_test.cc示例:https://github.com/google/benchmark/blob/b2e734087532897b7bb4c51a6b4f503060c9a20f/test/cxx03_test.cc

template <class T, class U>
void BM_template2(benchmark::State& state) {
    BM_empty(state);
}
BENCHMARK_TEMPLATE2(BM_template2, int, long);

template <class T>
void BM_template1(benchmark::State& state) {
    BM_empty(state);
}
BENCHMARK_TEMPLATE(BM_template1, long);
BENCHMARK_TEMPLATE1(BM_template1, int);

PS:宏定义的定义:https://github.com/google/benchmark/blob/2d088a9f2d41acb77afc99d045f669e1a21b61ef/include/benchmark/benchmark_api.h#L684

我们可以看到,宏的aa,b)参数放在<>中,并且它们被用作f<a,b>

// template<int arg>
// void BM_Foo(int iters);
//
// BENCHMARK_TEMPLATE(BM_Foo, 1);
//
// will register BM_Foo<1> as a benchmark.
#define BENCHMARK_TEMPLATE1(n, a) \
  BENCHMARK_PRIVATE_DECLARE(n) =  \
      (::benchmark::internal::RegisterBenchmarkInternal( \
        new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))

#define BENCHMARK_TEMPLATE2(n, a, b)                     \
  BENCHMARK_PRIVATE_DECLARE(n) =                         \
      (::benchmark::internal::RegisterBenchmarkInternal( \
        new ::benchmark::internal::FunctionBenchmark(    \
            #n "<" #a "," #b ">", n<a, b>)))

#define BENCHMARK_TEMPLATE(n, ...)           \
  BENCHMARK_PRIVATE_DECLARE(n) =             \
      (::benchmark::internal::RegisterBenchmarkInternal( \
        new ::benchmark::internal::FunctionBenchmark( \
        #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))

因此,BENCHMARK_TEMPLATE 无法在多个变量上迭代并从一行中定义您的函数的多个变体。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接