2

I have a code snippet I need to benchmark composed of 2 parts, first the state needs to be set exactly once, next I need to actually benchmark a function.

My code looks like this:

static void BM_LoopTime(benchmark::State& state) 
{
    MasterEngine engine;
    for (auto _ : state)
    {
        engine.LoopOnce();
    }
}
BENCHMARK(BM_LoopTime);

In my output I am getting:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Pointer already set                                                             
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Multiple times, which is a custom error message that indicates a very important pointer that should only ever be touched once is trying to be overwritten.

Calling that code multiple times is undefined behaviour in my implementation. How can I call the object initialization exactly once and then tell it to call the loop?

Makogan
  • 8,208
  • 7
  • 44
  • 112
  • 1
    Maybe you want to make MasterEngine a singleton object in your project? You can just keep a flag around stating whether or not the object has already been created. if not, create it. Then call LoopOnce. – Erix May 28 '20 at 01:47
  • Singletons are global scope, that is the primary reason I am not defining it as a singleton. – Makogan May 28 '20 at 01:54
  • In this case, having a pointer to the `MasterEngine` in global scope is likely the right way to go. Something like: `static MasterEngine* engine() { static MasterEngine eng; return ŋ }` would work well for the benchmarks. It's essentially what you're doing with the fixtures in your answer below. – dma Jun 01 '20 at 14:35
  • @dma Yes but Ideally I don't want to redesign my code just to get it working on a benchmarking library. I am trying to avoid having anything global as much as possible. – Makogan Jun 02 '20 at 01:45

1 Answers1

2

This is a work around that I found that's good enough for my use case but I am still looking for better solutions:

class MyFixture : public benchmark::Fixture 
{
public:
    std::unique_ptr<MasterEngine> engine;

    void SetUp(const ::benchmark::State& state) 
    {
        if(engine.get() == nullptr)
            engine = std::make_unique<MasterEngine>();
    }

    void TearDown(const ::benchmark::State& state) 
    {
    }
};
Makogan
  • 8,208
  • 7
  • 44
  • 112