c++11 - 谷歌/基准 : BENCHMARK_TEMPLATE syntax

标签 c++11 benchmarking

我想在 float 上运行 google/benchmark , doublelong double .

鉴于 BENCHMARK_TEMPLATE example ,我尝试了以下方法:

#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 创建三个基准,但它不会编译!

创建模板化谷歌基准测试的正确语法是什么?是我的心智模型 BENCHMARK_TEMPLATE应该可以正常工作,如果可以,我该如何修复此代码?

最佳答案

您使用 BENCHMARK_TEMPLATE以错误的方式与你

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

https://github.com/google/benchmark/的readme文件说
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)

所以,BENCHMARK_TEMPLATE with arg1 用于具有一个模板参数的函数,而 arg1 和 arg2 用于具有两个模板参数的函数。您的 BM_PowTemplated只有一个参数,所以不能使用 BENCHMARK_TEMPLATE有 3 个参数。

查询 test/cxx03_test.cc google/benchmark 例如: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

我们可以看到a ( a, 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无法迭代多个变体并从一行定义函数的多个变体。

关于c++11 - 谷歌/基准 : BENCHMARK_TEMPLATE syntax,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38023017/

相关文章:

c++ - 为基准测试创建随机 vector 的最快方法

c - 尽可能高效地评估具有约 60,000 个短符号表达式的 vector (Matlab,C)

c++ - 没有额外的实例方法和变量的对象切片

java - 如何用 Java 编写正确的微基准测试?

c++ - C++11 thread_local 变量可以从父线程继承它的初始值吗?

c++ - unique_ptr 成员,私有(private)复制构造函数与移动构造函数

c++ - 防止或阻止 cpu 数据缓存加载

windows - 在 Windows 和 Linux/Ubuntu 上运行的基准测试软件

c++ - 从 vector 中删除项目时出现 Valgrind 错误

c++ - 编译 C++ 线程