Google Benchmark BaseClass初始化发生在静态变量赋值导致问题之前



我想使用谷歌基准运行我的代码,其中包含一个静态全局变量。在基准测试的基类中,我需要读取这个变量来执行一些设置。但是,当基准基类初始化时,该静态变量尚未初始化,从而导致问题。

下面的最小复制示例包含三个文件:test.h, test.ccbenchmark_main.ccbenchmark_main.cc包含一个基准基类Init。它的构造函数读取data变量。但是此时,data变量仍然为空。

问题:是否有一种方法使data变量初始化发生在基类初始化之前?我们也欢迎任何其他的解决方法。

test.h

#include <array>
#include <vector>
using namespace std;
const vector<int>& func(int);

test.cc

#include "test.h"
const array<vector<int>,5> data = {
        vector<int>({1}),
        {2,3},
        {4,5},
        {6,7},
        {8}
};
const vector<int>& func(int index) {
        return data[index];
}

benchmark_main.cc

#include <benchmark/benchmark.h>
#include <iostream>
#include "test.h"
class Init: public benchmark::Fixture {
protected:
public:
    Init() {
        std::cout << func(1)[0] << 'n';
    }
};
BENCHMARK_F(Init, A)(benchmark::State &state) {
  for (auto _ : state)
    std::cout << func(1)[0] << 'n';
}
BENCHMARK_MAIN();

你的问题是c++中的全局变量在不同的翻译单元(即。cc文件)之间具有未定义的初始化顺序。

我看到几个选项来解决它:

  1. 从test中移动代码。Cc到benchmark_main的顶部。因为全局变量是在单个文件中按照声明顺序初始化的。这在本例中是微不足道的,但在大型项目中就不那么容易了。将data全局变量改为func()中的静态变量。这可能在一定程度上影响性能,因为它将检查是否在每次调用函数时初始化静态。
  2. 有一些编译器特定的调整可以修改全局变量的初始化顺序。例如:https://learn.microsoft.com/en-us/cpp/preprocessor/init-seg?view=msvc-160
  3. 比起使用BENCHMARK_F宏,您可以更直接地使用API来避免在那里使用全局变量。Google benchmark custom main可能会帮到你。

最新更新