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 次。
所以我的问题是:
- 我如何才能 运行 在基准测试之前只设置一次代码,例如“std::cout << "Foo "<< std::endl”?
- 当我使用"state.iterations()"时,我想一个一个地得到“1, 2, 3 ..”,但是我总是得到0。我怎样才能得到迭代器的序列号?
在我的真实案例中,我想在多线程场景中运行一些存储引擎相关的代码。步骤如下:
- 打开与存储引擎的连接。让我们假设连接对象 CAN 在不同线程之间共享。
- 基于连接打开会话。让我们假设会话对象不能在线程之间共享。
- 运行 很多 db_related 操作,这是我唯一要进行基准测试的代码。
- 关闭会话,连接。
我有以下伪代码,但我认为它至少有 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();
}
}
问题:
- 难道我必须在这里使用全局变量DBConnection,以便每个线程都可以访问它吗?
- 假设"DBSession* session = conn.openSession();"可以在"conn is really set up"之前执行,我也不想每次都对openSession进行benchmark,请问如何解决?
我总共有 4 个问题,分为 2 个部分,如果您对我的代码有更多建议,那就更好了。谢谢!
我们 运行 对整个基准测试多次,以找到 运行 的最佳迭代次数,但是每个基准测试只 运行 一次运行。你做对了。
如果需要,您需要自己跟踪迭代次数。但是,如果您这样做了,那么您所进行的基准测试可能与迭代次数无关,迭代次数是动态确定的。如果你想要固定次数的迭代,你应该看看 State::KeepRunningBatch
.
具有连接全局作品,或夹具的静态成员。
我会添加一个显式等待连接在每个线程上建立。在打开会话之前循环中的某种 conn.IsReady()
。
给定以下代码
#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 次。
所以我的问题是:
- 我如何才能 运行 在基准测试之前只设置一次代码,例如“std::cout << "Foo "<< std::endl”?
- 当我使用"state.iterations()"时,我想一个一个地得到“1, 2, 3 ..”,但是我总是得到0。我怎样才能得到迭代器的序列号?
在我的真实案例中,我想在多线程场景中运行一些存储引擎相关的代码。步骤如下:
- 打开与存储引擎的连接。让我们假设连接对象 CAN 在不同线程之间共享。
- 基于连接打开会话。让我们假设会话对象不能在线程之间共享。
- 运行 很多 db_related 操作,这是我唯一要进行基准测试的代码。
- 关闭会话,连接。
我有以下伪代码,但我认为它至少有 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();
}
}
问题:
- 难道我必须在这里使用全局变量DBConnection,以便每个线程都可以访问它吗?
- 假设"DBSession* session = conn.openSession();"可以在"conn is really set up"之前执行,我也不想每次都对openSession进行benchmark,请问如何解决?
我总共有 4 个问题,分为 2 个部分,如果您对我的代码有更多建议,那就更好了。谢谢!
我们 运行 对整个基准测试多次,以找到 运行 的最佳迭代次数,但是每个基准测试只 运行 一次运行。你做对了。
如果需要,您需要自己跟踪迭代次数。但是,如果您这样做了,那么您所进行的基准测试可能与迭代次数无关,迭代次数是动态确定的。如果你想要固定次数的迭代,你应该看看
State::KeepRunningBatch
.
具有连接全局作品,或夹具的静态成员。
我会添加一个显式等待连接在每个线程上建立。在打开会话之前循环中的某种
conn.IsReady()
。