Google 基准代码设置

Google benchmark code Setup

给定以下代码

#include <benchmark/benchmark.h>
#include <iostream>

static void BM_foo(benchmark::State& state) {
  std::cout << "Foo "<< std::endl;
  for (auto _: state) {
    std::cout <<  state.iterations()  << " In loop " <<std::endl;
  }
}

BENCHMARK(BM_foo);

BENCHMARK_MAIN();

我认为 std::cout << "Foo "<< std::endl;只会执行一次,但在我的测试中,它 运行s 7 次。

所以我的问题是:

  1. 我如何才能 运行 在基准测试之前只设置一次代码,例如“std::cout << "Foo "<< std::endl”?
  2. 当我使用"state.iterations()"时,我想一个一个地得到“1, 2, 3 ..”,但是我总是得到0。我怎样才能得到迭代器的序列号?

在我的真实案例中,我想在多线程场景中运行一些存储引擎相关的代码。步骤如下:

  1. 打开与存储引擎的连接。让我们假设连接对象 CAN 在不同线程之间共享。
  2. 基于连接打开会话。让我们假设会话对象不能在线程之间共享。
  3. 运行 很多 db_related 操作,这是我唯一要进行基准测试的代码。
  4. 关闭会话,连接。

我有以下伪代码,但我认为它至少有 2 个问题。

DBConnection* conn; // global variables, so that each thread can run access it.

static void BM_db_insert(benchmark::State& state) {
  if (state.thread_index == 0) {
    # only let 1 thread to setup the DBConnections
    conn = openDBConn();
  }
  DBSession* session = conn.openSession();
  for (auto _ : state) {
    session.insertOp(id, ..); 
  }
  session.close();
  if (state.thread_index == 0) {
    conn.close();
  }
}

问题:

  1. 难道我必须在这里使用全局变量DBConnection,以便每个线程都可以访问它吗?
  2. 假设"DBSession* session = conn.openSession();"可以在"conn is really set up"之前执行,我也不想每次都对openSession进行benchmark,请问如何解决?

我总共有 4 个问题,分为 2 个部分,如果您对我的代码有更多建议,那就更好了。谢谢!

  1. 我们 运行 对整个基准测试多次,以找到 运行 的最佳迭代次数,但是每个基准测试只 运行 一次运行。你做对了。

  2. 如果需要,您需要自己跟踪迭代次数。但是,如果您这样做了,那么您所进行的基准测试可能与迭代次数无关,迭代次数是动态确定的。如果你想要固定次数的迭代,你应该看看 State::KeepRunningBatch.


  1. 具有连接全局作品,或夹具的静态成员。

  2. 我会添加一个显式等待连接在每个线程上建立。在打开会话之前循环中的某种 conn.IsReady()