Google基准代码设置

时间:2018-05-19 13:39:44

标签: c++ google-benchmark

给出以下代码

#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&lt;&lt; “Foo”&lt;&lt;的std :: ENDL;将只执行一次,但在我的测试期间,它会运行7次。

所以我的问题是:

  1. 如何在基准测试之前只运行一次设置代码,例如“std :: cout&lt;&lt;”Foo“&lt;&lt; std :: endl”?
  2. 当我使用“state.iterations()”时,我希望逐个获得“1,2,3 ..”但是我会得到0.我怎样才能得到迭代器的seq数?
  3. 在我的实际案例中,我想在多线程场景中运行一些与存储引擎相关的代码。这样的步骤:

    1. 打开与存储引擎的连接。我们假设连接对象 CAN 在不同的线程之间共享。
    2. 基于连接打开会话。我们假设会话对象不能在线程之间共享。
    3. 运行许多db_related操作,这是我想要进行基准测试的唯一代码。
    4. 关闭会话,连接。
    5. 我有以下伪代码,但我认为它至少有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确实设置”之前执行,我也不想每次都对openSession进行基准测试,我该如何解决这个问题呢?
      3. 所以我总共分为两部分提出4个问题,如果你对我的代码有更多的建议,那就更好了。谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

    1. 使连接全局工作,或者夹具的静态成员。

    2. 我会添加一个明确的等待,以便在每个线程上设置连接。在打开会话之前,循环中有某种conn.IsReady()