1 // Copyright 2015 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef BENCHMARK_RUNNER_H_ 16 #define BENCHMARK_RUNNER_H_ 17 18 #include <thread> 19 #include <vector> 20 21 #include "benchmark_api_internal.h" 22 #include "internal_macros.h" 23 #include "perf_counters.h" 24 #include "thread_manager.h" 25 26 namespace benchmark { 27 28 BM_DECLARE_string(benchmark_min_time); 29 BM_DECLARE_double(benchmark_min_warmup_time); 30 BM_DECLARE_int32(benchmark_repetitions); 31 BM_DECLARE_bool(benchmark_report_aggregates_only); 32 BM_DECLARE_bool(benchmark_display_aggregates_only); 33 BM_DECLARE_string(benchmark_perf_counters); 34 35 namespace internal { 36 37 extern MemoryManager* memory_manager; 38 39 struct RunResults { 40 std::vector<BenchmarkReporter::Run> non_aggregates; 41 std::vector<BenchmarkReporter::Run> aggregates_only; 42 43 bool display_report_aggregates_only = false; 44 bool file_report_aggregates_only = false; 45 }; 46 47 struct BENCHMARK_EXPORT BenchTimeType { 48 enum { ITERS, TIME } tag; 49 union { 50 IterationCount iters; 51 double time; 52 }; 53 }; 54 55 BENCHMARK_EXPORT 56 BenchTimeType ParseBenchMinTime(const std::string& value); 57 58 class BenchmarkRunner { 59 public: 60 BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_, 61 benchmark::internal::PerfCountersMeasurement* pmc_, 62 BenchmarkReporter::PerFamilyRunReports* reports_for_family); 63 GetNumRepeats()64 int GetNumRepeats() const { return repeats; } 65 HasRepeatsRemaining()66 bool HasRepeatsRemaining() const { 67 return GetNumRepeats() != num_repetitions_done; 68 } 69 70 void DoOneRepetition(); 71 72 RunResults&& GetResults(); 73 GetReportsForFamily()74 BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const { 75 return reports_for_family; 76 } 77 GetMinTime()78 double GetMinTime() const { return min_time; } 79 HasExplicitIters()80 bool HasExplicitIters() const { return has_explicit_iteration_count; } 81 GetIters()82 IterationCount GetIters() const { return iters; } 83 84 private: 85 RunResults run_results; 86 87 const benchmark::internal::BenchmarkInstance& b; 88 BenchmarkReporter::PerFamilyRunReports* reports_for_family; 89 90 BenchTimeType parsed_benchtime_flag; 91 const double min_time; 92 const double min_warmup_time; 93 bool warmup_done; 94 const int repeats; 95 const bool has_explicit_iteration_count; 96 97 int num_repetitions_done = 0; 98 99 std::vector<std::thread> pool; 100 101 std::vector<MemoryManager::Result> memory_results; 102 103 IterationCount iters; // preserved between repetitions! 104 // So only the first repetition has to find/calculate it, 105 // the other repetitions will just use that precomputed iteration count. 106 107 PerfCountersMeasurement* const perf_counters_measurement_ptr = nullptr; 108 109 struct IterationResults { 110 internal::ThreadManager::Result results; 111 IterationCount iters; 112 double seconds; 113 }; 114 IterationResults DoNIterations(); 115 116 IterationCount PredictNumItersNeeded(const IterationResults& i) const; 117 118 bool ShouldReportIterationResults(const IterationResults& i) const; 119 120 double GetMinTimeToApply() const; 121 122 void FinishWarmUp(const IterationCount& i); 123 124 void RunWarmUp(); 125 }; 126 127 } // namespace internal 128 129 } // end namespace benchmark 130 131 #endif // BENCHMARK_RUNNER_H_ 132