diff --git a/README.md b/README.md index 9df94a3a..0af13fec 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,13 @@ measuring the speed of `memcpy()` calls of different lengths: ```c++ static void BM_memcpy(benchmark::State& state) { - char* src = new char[state.range_x()]; - char* dst = new char[state.range_x()]; - memset(src, 'x', state.range_x()); + char* src = new char[state.range(0)]; + char* dst = new char[state.range(0)]; + memset(src, 'x', state.range(0)); while (state.KeepRunning()) - memcpy(dst, src, state.range_x()); + memcpy(dst, src, state.range(0)); state.SetBytesProcessed(int64_t(state.iterations()) * - int64_t(state.range_x())); + int64_t(state.range(0))); delete[] src; delete[] dst; } @@ -70,7 +70,7 @@ BENCHMARK(BM_memcpy)->RangeMultiplier(2)->Range(8, 8<<10); ``` Now arguments generated are [ 8, 16, 32, 64, 128, 256, 512, 1024, 2k, 4k, 8k ]. -You might have a benchmark that depends on two inputs. For example, the +You might have a benchmark that depends on two or more inputs. For example, the following code defines a family of benchmarks for measuring the speed of set insertion. @@ -78,21 +78,21 @@ insertion. static void BM_SetInsert(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); - std::set data = ConstructRandomSet(state.range_x()); + std::set data = ConstructRandomSet(state.range(0)); state.ResumeTiming(); - for (int j = 0; j < state.range_y(); ++j) + for (int j = 0; j < state.range(1); ++j) data.insert(RandomNumber()); } } BENCHMARK(BM_SetInsert) - ->ArgPair(1<<10, 1) - ->ArgPair(1<<10, 8) - ->ArgPair(1<<10, 64) - ->ArgPair(1<<10, 512) - ->ArgPair(8<<10, 1) - ->ArgPair(8<<10, 8) - ->ArgPair(8<<10, 64) - ->ArgPair(8<<10, 512); + ->Args({1<<10, 1}) + ->Args({1<<10, 8}) + ->Args({1<<10, 64}) + ->Args({1<<10, 512}) + ->Args({8<<10, 1}) + ->Args({8<<10, 8}) + ->Args({8<<10, 64}) + ->Args({8<<10, 512}); ``` The preceding code is quite repetitive, and can be replaced with the following @@ -101,7 +101,7 @@ product of the two specified ranges and will generate a benchmark for each such pair. ```c++ -BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512); +BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); ``` For more complex patterns of inputs, passing a custom function to `Apply` allows @@ -113,7 +113,7 @@ and a sparse range on the second. static void CustomArguments(benchmark::internal::Benchmark* b) { for (int i = 0; i <= 10; ++i) for (int j = 32; j <= 1024*1024; j *= 8) - b->ArgPair(i, j); + b->Args({i, j}); } BENCHMARK(BM_SetInsert)->Apply(CustomArguments); ``` @@ -125,12 +125,12 @@ running time and the normalized root-mean square error of string comparison. ```c++ static void BM_StringCompare(benchmark::State& state) { - std::string s1(state.range_x(), '-'); - std::string s2(state.range_x(), '-'); + std::string s1(state.range(0), '-'); + std::string s2(state.range(0), '-'); while (state.KeepRunning()) { benchmark::DoNotOptimize(s1.compare(s2)); } - state.SetComplexityN(state.range_x()); + state.SetComplexityN(state.range(0)); } BENCHMARK(BM_StringCompare) ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity(benchmark::oN); @@ -162,14 +162,14 @@ template int BM_Sequential(benchmark::State& state) { Q q; typename Q::value_type v; while (state.KeepRunning()) { - for (int i = state.range_x(); i--; ) + for (int i = state.range(0); i--; ) q.push(v); - for (int e = state.range_x(); e--; ) + for (int e = state.range(0); e--; ) q.Wait(&v); } // actually messages, not bytes: state.SetBytesProcessed( - static_cast(state.iterations())*state.range_x()); + static_cast(state.iterations())*state.range(0)); } BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10); ``` @@ -284,7 +284,7 @@ can be reported back with `SetIterationTime`. ```c++ static void BM_ManualTiming(benchmark::State& state) { - int microseconds = state.range_x(); + int microseconds = state.range(0); std::chrono::duration sleep_duration { static_cast(microseconds) }; diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h index cced8cf0..1a481ac4 100644 --- a/include/benchmark/benchmark_api.h +++ b/include/benchmark/benchmark_api.h @@ -38,12 +38,12 @@ int main(int argc, char** argv) { // of memcpy() calls of different lengths: static void BM_memcpy(benchmark::State& state) { - char* src = new char[state.range_x()]; char* dst = new char[state.range_x()]; - memset(src, 'x', state.range_x()); + char* src = new char[state.range(0)]; char* dst = new char[state.range(0)]; + memset(src, 'x', state.range(0)); while (state.KeepRunning()) - memcpy(dst, src, state.range_x()); + memcpy(dst, src, state.range(0)); state.SetBytesProcessed(int64_t(state.iterations()) * - int64_t(state.range_x())); + int64_t(state.range(0))); delete[] src; delete[] dst; } BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10); @@ -60,27 +60,27 @@ BENCHMARK(BM_memcpy)->Range(8, 8<<10); static void BM_SetInsert(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); - set data = ConstructRandomSet(state.range_x()); + set data = ConstructRandomSet(state.range(0)); state.ResumeTiming(); - for (int j = 0; j < state.range_y(); ++j) + for (int j = 0; j < state.range(1); ++j) data.insert(RandomNumber()); } } BENCHMARK(BM_SetInsert) - ->ArgPair(1<<10, 1) - ->ArgPair(1<<10, 8) - ->ArgPair(1<<10, 64) - ->ArgPair(1<<10, 512) - ->ArgPair(8<<10, 1) - ->ArgPair(8<<10, 8) - ->ArgPair(8<<10, 64) - ->ArgPair(8<<10, 512); + ->Args({1<<10, 1}) + ->Args({1<<10, 8}) + ->Args({1<<10, 64}) + ->Args({1<<10, 512}) + ->Args({8<<10, 1}) + ->Args({8<<10, 8}) + ->Args({8<<10, 64}) + ->Args({8<<10, 512}); // The preceding code is quite repetitive, and can be replaced with // the following short-hand. The following macro will pick a few // appropriate arguments in the product of the two specified ranges // and will generate a microbenchmark for each such pair. -BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512); +BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); // For more complex patterns of inputs, passing a custom function // to Apply allows programmatic specification of an @@ -90,7 +90,7 @@ BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512); static void CustomArguments(benchmark::internal::Benchmark* b) { for (int i = 0; i <= 10; ++i) for (int j = 32; j <= 1024*1024; j *= 8) - b->ArgPair(i, j); + b->Args({i, j}); } BENCHMARK(BM_SetInsert)->Apply(CustomArguments); @@ -101,14 +101,14 @@ template int BM_Sequential(benchmark::State& state) { Q q; typename Q::value_type v; while (state.KeepRunning()) { - for (int i = state.range_x(); i--; ) + for (int i = state.range(0); i--; ) q.push(v); - for (int e = state.range_x(); e--; ) + for (int e = state.range(0); e--; ) q.Wait(&v); } // actually messages, not bytes: state.SetBytesProcessed( - static_cast(state.iterations())*state.range_x()); + static_cast(state.iterations())*state.range(0)); } BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10); @@ -153,6 +153,8 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); #include #include +#include + #include "macros.h" #if defined(BENCHMARK_HAS_CXX11) @@ -268,7 +270,7 @@ typedef double(BigOFunc)(int); // benchmark to use. class State { public: - State(size_t max_iters, bool has_x, int x, bool has_y, int y, + State(size_t max_iters, const std::vector& ranges, int thread_i, int n_threads); // Returns true if the benchmark should continue through another iteration. @@ -423,17 +425,9 @@ public: // Range arguments for this run. CHECKs if the argument has been set. BENCHMARK_ALWAYS_INLINE - int range_x() const { - assert(has_range_x_); - ((void)has_range_x_); // Prevent unused warning. - return range_x_; - } - - BENCHMARK_ALWAYS_INLINE - int range_y() const { - assert(has_range_y_); - ((void)has_range_y_); // Prevent unused warning. - return range_y_; + int range(std::size_t pos) const { + assert(range_.size() > pos); + return range_[pos]; } BENCHMARK_ALWAYS_INLINE @@ -444,11 +438,7 @@ private: bool finished_; size_t total_iterations_; - bool has_range_x_; - int range_x_; - - bool has_range_y_; - int range_y_; + std::vector range_; size_t bytes_processed_; size_t items_processed_; @@ -503,20 +493,18 @@ public: // REQUIRES: The function passed to the constructor must accept an arg1. Benchmark* DenseRange(int start, int limit, int step = 1); - // Run this benchmark once with "x,y" as the extra arguments passed + // Run this benchmark once with "args" as the extra arguments passed // to the function. - // REQUIRES: The function passed to the constructor must accept arg1,arg2. - Benchmark* ArgPair(int x, int y); + // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... + Benchmark* Args(const std::vector& args); - // Pick a set of values A from the range [lo1..hi1] and a set - // of values B from the range [lo2..hi2]. Run the benchmark for - // every pair of values in the cartesian product of A and B - // (i.e., for all combinations of the values in A and B). - // REQUIRES: The function passed to the constructor must accept arg1,arg2. - Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2); + // Run this benchmark once for a number of values picked from the + // ranges [start..limit]. (starts and limits are always picked.) + // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... + Benchmark* Ranges(const std::vector >& ranges); // Pass this benchmark object to *func, which can customize - // the benchmark by calling various methods like Arg, ArgPair, + // the benchmark by calling various methods like Arg, Args, // Threads, etc. Benchmark* Apply(void (*func)(Benchmark* benchmark)); @@ -725,11 +713,11 @@ protected: // Old-style macros #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) -#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->ArgPair((a1), (a2)) +#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)}) #define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t)) #define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi)) #define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ - BENCHMARK(n)->RangePair((l1), (h1), (l2), (h2)) + BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) #if __cplusplus >= 201103L diff --git a/src/benchmark.cc b/src/benchmark.cc index 8dadff71..515abd76 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -313,23 +313,20 @@ namespace internal { // Information kept per benchmark we may want to run struct Benchmark::Instance { - std::string name; - Benchmark* benchmark; - bool has_arg1; - int arg1; - bool has_arg2; - int arg2; - TimeUnit time_unit; - int range_multiplier; - bool use_real_time; - bool use_manual_time; - BigO complexity; - BigOFunc* complexity_lambda; - bool last_benchmark_instance; - int repetitions; - double min_time; - int threads; // Number of concurrent threads to use - bool multithreaded; // Is benchmark multi-threaded? + std::string name; + Benchmark* benchmark; + std::vector arg; + TimeUnit time_unit; + int range_multiplier; + bool use_real_time; + bool use_manual_time; + BigO complexity; + BigOFunc* complexity_lambda; + bool last_benchmark_instance; + int repetitions; + double min_time; + int threads; // Number of concurrent threads to use + bool multithreaded; // Is benchmark multi-threaded? }; // Class for managing registered benchmarks. Note that each registered @@ -362,8 +359,8 @@ public: void Unit(TimeUnit unit); void Range(int start, int limit); void DenseRange(int start, int limit, int step = 1); - void ArgPair(int start, int limit); - void RangePair(int lo1, int hi1, int lo2, int hi2); + void Args(const std::vector& args); + void Ranges(const std::vector>& ranges); void RangeMultiplier(int multiplier); void MinTime(double n); void Repetitions(int n); @@ -378,12 +375,13 @@ public: static void AddRange(std::vector* dst, int lo, int hi, int mult); + int ArgsCnt() const { return args_.empty() ? -1 : static_cast(args_.front().size()); } + private: friend class BenchmarkFamilies; std::string name_; - int arg_count_; - std::vector< std::pair > args_; // Args for all benchmark runs + std::vector< std::vector > args_; // Args for all benchmark runs TimeUnit time_unit_; int range_multiplier_; double min_time_; @@ -431,10 +429,10 @@ bool BenchmarkFamilies::FindBenchmarks( if (!bench_family) continue; BenchmarkImp* family = bench_family->imp_; - if (family->arg_count_ == -1) { - family->arg_count_ = 0; - family->args_.emplace_back(-1, -1); + if (family->ArgsCnt() == -1) { + family->Args({}); } + for (auto const& args : family->args_) { const std::vector* thread_counts = (family->thread_counts_.empty() @@ -445,10 +443,7 @@ bool BenchmarkFamilies::FindBenchmarks( Benchmark::Instance instance; instance.name = family->name_; instance.benchmark = bench_family.get(); - instance.has_arg1 = family->arg_count_ >= 1; - instance.arg1 = args.first; - instance.has_arg2 = family->arg_count_ == 2; - instance.arg2 = args.second; + instance.arg = args; instance.time_unit = family->time_unit_; instance.range_multiplier = family->range_multiplier_; instance.min_time = family->min_time_; @@ -461,12 +456,10 @@ bool BenchmarkFamilies::FindBenchmarks( instance.multithreaded = !(family->thread_counts_.empty()); // Add arguments to instance name - if (family->arg_count_ >= 1) { - AppendHumanReadable(instance.arg1, &instance.name); - } - if (family->arg_count_ >= 2) { - AppendHumanReadable(instance.arg2, &instance.name); + for (auto const& arg : args) { + AppendHumanReadable(arg, &instance.name); } + if (!IsZero(family->min_time_)) { instance.name += StringPrintF("/min_time:%0.3f", family->min_time_); } @@ -495,7 +488,7 @@ bool BenchmarkFamilies::FindBenchmarks( } BenchmarkImp::BenchmarkImp(const char* name) - : name_(name), arg_count_(-1), time_unit_(kNanosecond), + : name_(name), time_unit_(kNanosecond), range_multiplier_(kRangeMultiplier), min_time_(0.0), repetitions_(0), use_real_time_(false), use_manual_time_(false), complexity_(oNone) { @@ -505,9 +498,8 @@ BenchmarkImp::~BenchmarkImp() { } void BenchmarkImp::Arg(int x) { - CHECK(arg_count_ == -1 || arg_count_ == 1); - arg_count_ = 1; - args_.emplace_back(x, -1); + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); + args_.push_back({x}); } void BenchmarkImp::Unit(TimeUnit unit) { @@ -515,42 +507,54 @@ void BenchmarkImp::Unit(TimeUnit unit) { } void BenchmarkImp::Range(int start, int limit) { - CHECK(arg_count_ == -1 || arg_count_ == 1); - arg_count_ = 1; + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); std::vector arglist; AddRange(&arglist, start, limit, range_multiplier_); for (int i : arglist) { - args_.emplace_back(i, -1); + args_.push_back({i}); } } void BenchmarkImp::DenseRange(int start, int limit, int step) { - CHECK(arg_count_ == -1 || arg_count_ == 1); - arg_count_ = 1; + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); CHECK_GE(start, 0); CHECK_LE(start, limit); - for (int arg = start; arg <= limit; arg += step) { - args_.emplace_back(arg, -1); + for (int arg = start; arg <= limit; arg+= step) { + args_.push_back({arg}); } } -void BenchmarkImp::ArgPair(int x, int y) { - CHECK(arg_count_ == -1 || arg_count_ == 2); - arg_count_ = 2; - args_.emplace_back(x, y); +void BenchmarkImp::Args(const std::vector& args) +{ + args_.push_back(args); } -void BenchmarkImp::RangePair(int lo1, int hi1, int lo2, int hi2) { - CHECK(arg_count_ == -1 || arg_count_ == 2); - arg_count_ = 2; - std::vector arglist1, arglist2; - AddRange(&arglist1, lo1, hi1, range_multiplier_); - AddRange(&arglist2, lo2, hi2, range_multiplier_); +void BenchmarkImp::Ranges(const std::vector>& ranges) { + std::vector> arglists(ranges.size()); + int total = 1; + for (std::size_t i = 0; i < ranges.size(); i++) { + AddRange(&arglists[i], ranges[i].first, ranges[i].second, range_multiplier_); + total *= arglists[i].size(); + } - for (int i : arglist1) { - for (int j : arglist2) { - args_.emplace_back(i, j); + std::vector ctr(total, 0); + + for (int i = 0; i < total; i++) { + std::vector tmp; + + for (std::size_t j = 0; j < arglists.size(); j++) { + tmp.push_back(arglists[j][ctr[j]]); + } + + args_.push_back(tmp); + + for (std::size_t j = 0; j < arglists.size(); j++) { + if (ctr[j] + 1 < arglists[j].size()) { + ++ctr[j]; + break; + } + ctr[j] = 0; } } } @@ -648,6 +652,7 @@ Benchmark::Benchmark(Benchmark const& other) } Benchmark* Benchmark::Arg(int x) { + CHECK(imp_->ArgsCnt() == -1 || imp_->ArgsCnt() == 1); imp_->Arg(x); return this; } @@ -658,22 +663,27 @@ Benchmark* Benchmark::Unit(TimeUnit unit) { } Benchmark* Benchmark::Range(int start, int limit) { + CHECK(imp_->ArgsCnt() == -1 || imp_->ArgsCnt() == 1); imp_->Range(start, limit); return this; } +Benchmark* Benchmark::Ranges(const std::vector>& ranges) +{ + CHECK(imp_->ArgsCnt() == -1 || imp_->ArgsCnt() == static_cast(ranges.size())); + imp_->Ranges(ranges); + return this; +} + Benchmark* Benchmark::DenseRange(int start, int limit, int step) { + CHECK(imp_->ArgsCnt() == -1 || imp_->ArgsCnt() == 1); imp_->DenseRange(start, limit, step); return this; } -Benchmark* Benchmark::ArgPair(int x, int y) { - imp_->ArgPair(x, y); - return this; -} - -Benchmark* Benchmark::RangePair(int lo1, int hi1, int lo2, int hi2) { - imp_->RangePair(lo1, hi1, lo2, hi2); +Benchmark* Benchmark::Args(const std::vector& args) { + CHECK(imp_->ArgsCnt() == -1 || imp_->ArgsCnt() == static_cast(args.size())); + imp_->Args(args); return this; } @@ -751,7 +761,7 @@ namespace { void RunInThread(const benchmark::internal::Benchmark::Instance* b, size_t iters, int thread_id, ThreadStats* total) EXCLUDES(GetBenchmarkLock()) { - State st(iters, b->has_arg1, b->arg1, b->has_arg2, b->arg2, thread_id, b->threads); + State st(iters, b->arg, thread_id, b->threads); b->benchmark->Run(st); CHECK(st.iterations() == st.max_iterations) << "Benchmark returned before State::KeepRunning() returned false!"; @@ -925,11 +935,10 @@ RunBenchmark(const benchmark::internal::Benchmark::Instance& b, } // namespace -State::State(size_t max_iters, bool has_x, int x, bool has_y, int y, +State::State(size_t max_iters, const std::vector& ranges, int thread_i, int n_threads) : started_(false), finished_(false), total_iterations_(0), - has_range_x_(has_x), range_x_(x), - has_range_y_(has_y), range_y_(y), + range_(ranges), bytes_processed_(0), items_processed_(0), complexity_n_(0), error_occurred_(false), diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3b8f7c91..93855a38 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -51,6 +51,9 @@ add_test(register_benchmark_test register_benchmark_test --benchmark_min_time=0. compile_benchmark_test(map_test) add_test(map_test map_test --benchmark_min_time=0.01) +compile_benchmark_test(multiple_ranges_test) +add_test(multiple_ranges_test multiple_ranges_test --benchmark_min_time=0.01) + compile_benchmark_test(reporter_output_test) add_test(reporter_output_test reporter_output_test --benchmark_min_time=0.01) diff --git a/test/basic_test.cc b/test/basic_test.cc index 34354154..570ff226 100644 --- a/test/basic_test.cc +++ b/test/basic_test.cc @@ -14,7 +14,7 @@ BENCHMARK(BM_empty)->ThreadPerCpu(); void BM_spin_empty(benchmark::State& state) { while (state.KeepRunning()) { - for (int x = 0; x < state.range_x(); ++x) { + for (int x = 0; x < state.range(0); ++x) { benchmark::DoNotOptimize(x); } } @@ -23,11 +23,11 @@ BASIC_BENCHMARK_TEST(BM_spin_empty); BASIC_BENCHMARK_TEST(BM_spin_empty)->ThreadPerCpu(); void BM_spin_pause_before(benchmark::State& state) { - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } while(state.KeepRunning()) { - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } } @@ -39,11 +39,11 @@ BASIC_BENCHMARK_TEST(BM_spin_pause_before)->ThreadPerCpu(); void BM_spin_pause_during(benchmark::State& state) { while(state.KeepRunning()) { state.PauseTiming(); - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } state.ResumeTiming(); - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } } @@ -64,11 +64,11 @@ BENCHMARK(BM_pause_during)->UseRealTime()->ThreadPerCpu(); void BM_spin_pause_after(benchmark::State& state) { while(state.KeepRunning()) { - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } } - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } } @@ -77,15 +77,15 @@ BASIC_BENCHMARK_TEST(BM_spin_pause_after)->ThreadPerCpu(); void BM_spin_pause_before_and_after(benchmark::State& state) { - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } while(state.KeepRunning()) { - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } } - for (int i = 0; i < state.range_x(); ++i) { + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(i); } } diff --git a/test/benchmark_test.cc b/test/benchmark_test.cc index 66f59564..fe7d82c6 100644 --- a/test/benchmark_test.cc +++ b/test/benchmark_test.cc @@ -67,7 +67,7 @@ BENCHMARK(BM_Factorial)->UseRealTime(); static void BM_CalculatePiRange(benchmark::State& state) { double pi = 0.0; while (state.KeepRunning()) - pi = CalculatePi(state.range_x()); + pi = CalculatePi(state.range(0)); std::stringstream ss; ss << pi; state.SetLabel(ss.str()); @@ -87,25 +87,25 @@ BENCHMARK(BM_CalculatePi)->ThreadPerCpu(); static void BM_SetInsert(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); - std::set data = ConstructRandomSet(state.range_x()); + std::set data = ConstructRandomSet(state.range(0)); state.ResumeTiming(); - for (int j = 0; j < state.range_y(); ++j) + for (int j = 0; j < state.range(1); ++j) data.insert(rand()); } - state.SetItemsProcessed(state.iterations() * state.range_y()); - state.SetBytesProcessed(state.iterations() * state.range_y() * sizeof(int)); + state.SetItemsProcessed(state.iterations() * state.range(1)); + state.SetBytesProcessed(state.iterations() * state.range(1) * sizeof(int)); } -BENCHMARK(BM_SetInsert)->RangePair(1<<10,8<<10, 1,10); +BENCHMARK(BM_SetInsert)->Ranges({{1<<10,8<<10}, {1,10}}); template static void BM_Sequential(benchmark::State& state) { ValueType v = 42; while (state.KeepRunning()) { Container c; - for (int i = state.range_x(); --i; ) + for (int i = state.range(0); --i; ) c.push_back(v); } - const size_t items_processed = state.iterations() * state.range_x(); + const size_t items_processed = state.iterations() * state.range(0); state.SetItemsProcessed(items_processed); state.SetBytesProcessed(items_processed * sizeof(v)); } @@ -117,8 +117,8 @@ BENCHMARK_TEMPLATE(BM_Sequential, std::vector, int)->Arg(512); #endif static void BM_StringCompare(benchmark::State& state) { - std::string s1(state.range_x(), '-'); - std::string s2(state.range_x(), '-'); + std::string s1(state.range(0), '-'); + std::string s2(state.range(0), '-'); while (state.KeepRunning()) benchmark::DoNotOptimize(s1.compare(s2)); } @@ -147,14 +147,14 @@ BENCHMARK(BM_SetupTeardown)->ThreadPerCpu(); static void BM_LongTest(benchmark::State& state) { double tracker = 0.0; while (state.KeepRunning()) { - for (int i = 0; i < state.range_x(); ++i) + for (int i = 0; i < state.range(0); ++i) benchmark::DoNotOptimize(tracker += i); } } BENCHMARK(BM_LongTest)->Range(1<<16,1<<28); static void BM_ParallelMemset(benchmark::State& state) { - int size = state.range_x() / sizeof(int); + int size = state.range(0) / sizeof(int); int thread_size = size / state.threads; int from = thread_size * state.thread_index; int to = from + thread_size; @@ -179,7 +179,7 @@ BENCHMARK(BM_ParallelMemset)->Arg(10 << 20)->ThreadRange(1, 4); static void BM_ManualTiming(benchmark::State& state) { size_t slept_for = 0; - int microseconds = state.range_x(); + int microseconds = state.range(0); std::chrono::duration sleep_duration { static_cast(microseconds) }; diff --git a/test/complexity_test.cc b/test/complexity_test.cc index f9e79bb8..6e903fbf 100644 --- a/test/complexity_test.cc +++ b/test/complexity_test.cc @@ -161,7 +161,7 @@ int AddComplexityTest(std::vector* console_out, std::vector* void BM_Complexity_O1(benchmark::State& state) { while (state.KeepRunning()) { } - state.SetComplexityN(state.range_x()); + state.SetComplexityN(state.range(0)); } BENCHMARK(BM_Complexity_O1) -> Range(1, 1<<18) -> Complexity(benchmark::o1); BENCHMARK(BM_Complexity_O1) -> Range(1, 1<<18) -> Complexity(); @@ -198,12 +198,12 @@ std::vector ConstructRandomVector(int size) { } void BM_Complexity_O_N(benchmark::State& state) { - auto v = ConstructRandomVector(state.range_x()); - const int item_not_in_vector = state.range_x()*2; // Test worst case scenario (item not in vector) + auto v = ConstructRandomVector(state.range(0)); + const int item_not_in_vector = state.range(0)*2; // Test worst case scenario (item not in vector) while (state.KeepRunning()) { benchmark::DoNotOptimize(std::find(v.begin(), v.end(), item_not_in_vector)); } - state.SetComplexityN(state.range_x()); + state.SetComplexityN(state.range(0)); } BENCHMARK(BM_Complexity_O_N) -> RangeMultiplier(2) -> Range(1<<10, 1<<16) -> Complexity(benchmark::oN); BENCHMARK(BM_Complexity_O_N) -> RangeMultiplier(2) -> Range(1<<10, 1<<16) -> Complexity([](int n) -> double{return n; }); @@ -227,11 +227,11 @@ ADD_COMPLEXITY_CASES(&ConsoleOutputTests, &JSONOutputTests, &CSVOutputTests, // ========================================================================= // static void BM_Complexity_O_N_log_N(benchmark::State& state) { - auto v = ConstructRandomVector(state.range_x()); + auto v = ConstructRandomVector(state.range(0)); while (state.KeepRunning()) { std::sort(v.begin(), v.end()); } - state.SetComplexityN(state.range_x()); + state.SetComplexityN(state.range(0)); } BENCHMARK(BM_Complexity_O_N_log_N) -> RangeMultiplier(2) -> Range(1<<10, 1<<16) -> Complexity(benchmark::oNLogN); BENCHMARK(BM_Complexity_O_N_log_N) -> RangeMultiplier(2) -> Range(1<<10, 1<<16) -> Complexity([](int n) {return n * std::log2(n); }); diff --git a/test/fixture_test.cc b/test/fixture_test.cc index bf800fda..226bb2a1 100644 --- a/test/fixture_test.cc +++ b/test/fixture_test.cc @@ -44,7 +44,7 @@ BENCHMARK_DEFINE_F(MyFixture, Bar)(benchmark::State& st) { assert(data.get() != nullptr); assert(*data == 42); } - st.SetItemsProcessed(st.range_x()); + st.SetItemsProcessed(st.range(0)); } BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42); BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42)->ThreadPerCpu(); diff --git a/test/map_test.cc b/test/map_test.cc index 5eccf8d3..729c012f 100644 --- a/test/map_test.cc +++ b/test/map_test.cc @@ -17,7 +17,7 @@ std::map ConstructRandomMap(int size) { // Basic version. static void BM_MapLookup(benchmark::State& state) { - const int size = state.range_x(); + const int size = state.range(0); while (state.KeepRunning()) { state.PauseTiming(); std::map m = ConstructRandomMap(size); @@ -34,7 +34,7 @@ BENCHMARK(BM_MapLookup)->Range(1 << 3, 1 << 12); class MapFixture : public ::benchmark::Fixture { public: void SetUp(const ::benchmark::State& st) { - m = ConstructRandomMap(st.range_x()); + m = ConstructRandomMap(st.range(0)); } void TearDown(const ::benchmark::State&) { @@ -45,7 +45,7 @@ class MapFixture : public ::benchmark::Fixture { }; BENCHMARK_DEFINE_F(MapFixture, Lookup)(benchmark::State& state) { - const int size = state.range_x(); + const int size = state.range(0); while (state.KeepRunning()) { for (int i = 0; i < size; ++i) { benchmark::DoNotOptimize(m.find(rand() % size)); diff --git a/test/multiple_ranges_test.cc b/test/multiple_ranges_test.cc new file mode 100644 index 00000000..a376941e --- /dev/null +++ b/test/multiple_ranges_test.cc @@ -0,0 +1,45 @@ +#include "benchmark/benchmark.h" + +#include +#include + +class MultipleRangesFixture : public ::benchmark::Fixture { + public: + MultipleRangesFixture() { + expectedValues = { + {1, 3, 5}, {1, 3, 8}, {1, 3, 15}, {2, 3, 5}, {2, 3, 8}, {2, 3, 15}, + {1, 4, 5}, {1, 4, 8}, {1, 4, 15}, {2, 4, 5}, {2, 4, 8}, {2, 4, 15}, + {1, 7, 5}, {1, 7, 8}, {1, 7, 15}, {2, 7, 5}, {2, 7, 8}, {2, 7, 15}, + {7, 6, 3} + }; + } + + void SetUp(const ::benchmark::State& state) { + std::vector ranges = {state.range(0), state.range(1), state.range(2)}; + + assert(expectedValues.find(ranges) != expectedValues.end()); + + actualValues.insert(ranges); + } + + virtual ~MultipleRangesFixture() { + assert(actualValues.size() == expectedValues.size()); + } + + std::set> expectedValues; + std::set> actualValues; +}; + + +BENCHMARK_DEFINE_F(MultipleRangesFixture, Empty)(benchmark::State& state) { + while (state.KeepRunning()) { + int product = state.range(0) * state.range(1) * state.range(2); + for (int x = 0; x < product; x++) { + benchmark::DoNotOptimize(x); + } + } +} + +BENCHMARK_REGISTER_F(MultipleRangesFixture, Empty)->RangeMultiplier(2)->Ranges({{1, 2}, {3, 7}, {5, 15}})->Args({7, 6, 3}); + +BENCHMARK_MAIN() diff --git a/test/options_test.cc b/test/options_test.cc index 78cedaea..06bc9c2e 100644 --- a/test/options_test.cc +++ b/test/options_test.cc @@ -9,7 +9,7 @@ void BM_basic(benchmark::State& state) { } void BM_basic_slow(benchmark::State& state) { - std::chrono::milliseconds sleep_duration(state.range_x()); + std::chrono::milliseconds sleep_duration(state.range(0)); while (state.KeepRunning()) { std::this_thread::sleep_for( std::chrono::duration_cast(sleep_duration) @@ -25,8 +25,8 @@ BENCHMARK(BM_basic_slow)->Arg(1000)->Unit(benchmark::kMillisecond); BENCHMARK(BM_basic)->Range(1, 8); BENCHMARK(BM_basic)->RangeMultiplier(2)->Range(1, 8); BENCHMARK(BM_basic)->DenseRange(10, 15); -BENCHMARK(BM_basic)->ArgPair(42, 42); -BENCHMARK(BM_basic)->RangePair(64, 512, 64, 512); +BENCHMARK(BM_basic)->Args({42, 42}); +BENCHMARK(BM_basic)->Ranges({{64, 512}, {64, 512}}); BENCHMARK(BM_basic)->MinTime(0.7); BENCHMARK(BM_basic)->UseRealTime(); BENCHMARK(BM_basic)->ThreadRange(2, 4); diff --git a/test/reporter_output_test.cc b/test/reporter_output_test.cc index 7f802773..0439fa68 100644 --- a/test/reporter_output_test.cc +++ b/test/reporter_output_test.cc @@ -185,7 +185,7 @@ ADD_CASES(&CSVOutputTests, { void BM_Complexity_O1(benchmark::State& state) { while (state.KeepRunning()) { } - state.SetComplexityN(state.range_x()); + state.SetComplexityN(state.range(0)); } BENCHMARK(BM_Complexity_O1)->Range(1, 1<<18)->Complexity(benchmark::o1); diff --git a/test/skip_with_error_test.cc b/test/skip_with_error_test.cc index dafbd64d..1ad13665 100644 --- a/test/skip_with_error_test.cc +++ b/test/skip_with_error_test.cc @@ -74,7 +74,7 @@ ADD_CASES("BM_error_before_running", void BM_error_during_running(benchmark::State& state) { int first_iter = true; while (state.KeepRunning()) { - if (state.range_x() == 1 && state.thread_index <= (state.threads / 2)) { + if (state.range(0) == 1 && state.thread_index <= (state.threads / 2)) { assert(first_iter); first_iter = false; state.SkipWithError("error message"); @@ -116,7 +116,7 @@ ADD_CASES( void BM_error_while_paused(benchmark::State& state) { bool first_iter = true; while (state.KeepRunning()) { - if (state.range_x() == 1 && state.thread_index <= (state.threads / 2)) { + if (state.range(0) == 1 && state.thread_index <= (state.threads / 2)) { assert(first_iter); first_iter = false; state.PauseTiming();