我想在 float
上运行 google/benchmark , double
和 long 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.cctemplate <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/