Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google benchmark with command line args. Writing my own main function?

I have a code that goes something like:

...
void benchMark(benchmark::State& state){
    maxCapacity = state.range(0);
    // set up some stuff
    for (auto _ : state){
        // time this code
    }
}

BENCHMARK(benchMark)->DenseRange(2, 10, 1);
BENCHMARK_MAIN();

I want to change it to something like:

...
void benchMark(benchmark::State& state){
    maxCapacity = state.range(0);
    // set up some stuff
    for (auto _ : state){
        // time this code
    }
}

int main(){
    BENCHMARK(benchMark)->DenseRange(2, 10, 1);
}

I'm doing this just so that I can provide command line argument support to the code later. Now this code compiles successfully, but I don't get any output at all. The code doesn't even run I guess. The first code takes like 5 mins to complete, but the second one completes execution almost instantly. What am I doing wrong?

Any help would be great. Thanks..

EDIT:

Since I can't share the full code, here's a minimum reproducible example:

#include <iostream>
#include <benchmark/benchmark.h>
using namespace std;

void pointQuery(int maxCapacity){
    long sum = 0;
    for(int i=0; i<100000*maxCapacity; i++){
        for(int j=0; j<100000*maxCapacity; j++)
            sum--;
        sum+=i;
    }
    cout<<sum<<endl;
}

void benchMark(benchmark::State& state){
    int maxCapacity = state.range(0);
    for (auto _ : state)
        pointQuery(maxCapacity);
}

BENCHMARK(benchMark)->DenseRange(2, 10, 1);
BENCHMARK_MAIN();
// int main(){
//     BENCHMARK(benchMark)->DenseRange(2, 10, 1);
// }
like image 557
Ankit Kumar Avatar asked Mar 17 '20 06:03

Ankit Kumar


2 Answers

if you just copy the contents of the BENCHMARK_MAIN macro to your test file it should work:

int main(int argc, char** argv) {
    BENCHMARK(benchMark)->DenseRange(2, 10, 1);

    //these entries are from BENCHMARK_MAIN
    ::benchmark::Initialize(&argc, argv);
    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
    ::benchmark::RunSpecifiedBenchmarks();
  }
like image 50
pero_hero Avatar answered Nov 13 '22 04:11

pero_hero


The documentation suggest using benchmark::RegisterBenchmark:

Unlike the BENCHMARK registration macros, which can only be used at the global scope, the RegisterBenchmark can be called anywhere. This allows for benchmark tests to be registered programmatically. ... For Example:

auto BM_test = [](benchmark::State& st, auto Inputs) { /* ... */ };

int main(int argc, char** argv) {
  for (auto& test_input : { /* ... */ })
      benchmark::RegisterBenchmark(test_input.name(), BM_test, test_input);
  benchmark::Initialize(&argc, argv);
  benchmark::RunSpecifiedBenchmarks();
}
like image 36
murfel Avatar answered Nov 13 '22 04:11

murfel