如何将参数传递给 Google Benchmark 程序

问题描述 投票:0回答:3

我有一个 C++ Google 基准测试程序。它使用 Google 的

BENCHMARK_MAIN()
方法。现在我用 Go 脚本调用并执行编译后的程序。有没有办法将参数传递到我的基准程序中? (我知道 main 方法的常用方法,但我不确定如何在 Googletest 中执行此操作,因为它是在
benchmark_api.h
中实现的,我不能只是更改它。)

更新:

到目前为止,我将宏主体复制到我的

benchmark.cpp
中并添加了一行。这不是一个很好的解决方案,因为 Google 对此宏的可能更改(例如名称更改或添加的代码行)不会影响我的副本。终于可以用了。

int main (int argc, char** argv)
{
    MyNamespace::conf = {argv[1]};
    ::benchmark::Initialize (&argc, argv);
    ::benchmark::RunSpecifiedBenchmarks ();
}
c++ google-api parameter-passing benchmarking google-benchmark
3个回答
6
投票

破解整个

BENCHMARK_MAIN
功能当然是一种方法,但在我看来,这真的很麻烦而且很难看。所以我只是提出一个不同的方法:

// 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 脚本中,您使用正则表达式过滤器调用基准测试:

./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

4
投票

我想通过添加该库还支持以下内容来扩展 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-arguments


0
投票

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
argv
...,并且完整保留未知选项和位置参数(
argc
也被修改)。

这意味着可以打电话

benchmark::Initialize(&argc, argv);

然后从清理后的

argc
argv
获取程序特定的参数。

© www.soinside.com 2019 - 2024. All rights reserved.