如何将参数传递给Google基准测试程序



我有一个C++谷歌基准测试程序。它使用谷歌的BENCHMARK_MAIN()方法。现在我用Go脚本调用并执行编译后的程序。有没有一种方法可以将参数传递到我的基准测试程序中?(我知道主方法的通用方法,但我不确定如何在Googletest中实现,因为它是在benchmark_api.h中实现的,我不能只是改变它。(

更新:

到目前为止,我将宏体复制到我的benchmark.cpp中,并添加了一行。这不是一个好的解决方案,因为谷歌可能对这个宏进行的更改(比如更改名称或添加代码行(不会影响我的副本。它终于起作用了。

int main (int argc, char** argv)
{
MyNamespace::conf = {argv[1]};
::benchmark::Initialize (&argc, argv);
::benchmark::RunSpecifiedBenchmarks ();
}

破解整个BENCHMARK_MAIN函数当然是一种方法,但IMO确实很麻烦,也很难看。所以我只想提出一种不同的方法:

// define your chunksize and iteration count combinations here (for i and j) 
static void CustomArguments(benchmark::internal::Benchmark* b) {
for (int i = 0; i <= 10; ++i)
for (int j = 0; j <= 50; ++j)
b->Args({i, j});
}
// the string (name of the used function is passed later)
static void TestBenchmark(benchmark::State& state, std::string func_name) {
// cout for testing purposes
std::cout << state.range(0) /* = i */ << " " << state.range(1) /* = j */ 
<< " " << func_name << std::endl;
for (auto _ : state) {
// do whatever with i and j and func_name
}
}
// This macro is used to pass the string "function_name1/2/3" 
// as a parameter to TestBenchmark
BENCHMARK_CAPTURE(TestBenchmark, benchmark_name1, "function_name1")
->Apply(CustomArguments);
BENCHMARK_CAPTURE(TestBenchmark, benchmark_name2, "function_name2")
->Apply(CustomArguments);
BENCHMARK_CAPTURE(TestBenchmark, benchmark_name3, "function_name3")
->Apply(CustomArguments);
BENCHMARK_MAIN()

然后在go脚本中,使用regex过滤器调用基准:
./prog_name --benchmark_filter=InsertRegexFilterHere

例如:
./prog_name --benchmark_filter=TestBenchmark/benchmark_name2/5/35

上面的例子将调用基准测试,并传递"function_name2"、5和35(这些是块大小和迭代计数的值(,因此输出将类似于:

------------------------------------------------------------------------------
Benchmark                                       Time           CPU Iterations
------------------------------------------------------------------------------
TestBenchmark/benchmark_name2/5/35               2 ns          2 ns  308047644

我想通过添加库还支持以下内容来扩展Mike van Dyke的回答:

static void BM_SetInsert(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) {
state.PauseTiming();
data = ConstructRandomSet(state.range(0));
state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber());
}
}
BENCHMARK(BM_SetInsert)
->Args({1<<10, 128})
->Args({2<<10, 128})
->Args({4<<10, 128})
->Args({8<<10, 128})
->Args({1<<10, 512})
->Args({2<<10, 512})
->Args({4<<10, 512})
->Args({8<<10, 512});

在您的基准测试中,state.range(0)state.range(1)现在分别引用第一个和第二个参数。查看更多@https://github.com/google/benchmark#passing-自变量

如中所述https://github.com/google/benchmark/blob/main/docs/user_guide.md#using-registerbenchmarkname-fn-args,基准测试可以像这样交互注册:

auto BM_test = [](benchmark::State& st, auto Inputs) { /* ... */ };
int main(int argc, char** argv) {
for (auto& test_input : { /* ... */ })
benchmark::RegisterBenchmark(test_input.name(), BM_test, test_input);
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
benchmark::Shutdown();
}

需要注意的是,如果benchmark看到未知参数,它通常会中止。benchmark::Initialize的情况并非如此。此函数删除所有特定于benchmark的选项,如--benchmark_filter--benchmark_out。。。从CCD_ 14,它保留未知选项和位置参数不变(CCD_ 15也被修改(。

这意味着可以调用

benchmark::Initialize(&argc, argv);

然后从清理后的CCD_ 16和CCD_。

最新更新