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 extern ProfilerManager* profiler_manager; 39 40 struct RunResults { 41 std::vector<BenchmarkReporter::Run> non_aggregates; 42 std::vector<BenchmarkReporter::Run> aggregates_only; 43 44 bool display_report_aggregates_only = false; 45 bool file_report_aggregates_only = false; 46 }; 47 48 struct BENCHMARK_EXPORT BenchTimeType { 49 enum { ITERS, TIME } tag; 50 union { 51 IterationCount iters; 52 double time; 53 }; 54 }; 55 56 BENCHMARK_EXPORT 57 BenchTimeType ParseBenchMinTime(const std::string& value); 58 59 class BenchmarkRunner { 60 public: 61 BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_, 62 benchmark::internal::PerfCountersMeasurement* pmc_, 63 BenchmarkReporter::PerFamilyRunReports* reports_for_family); 64 GetNumRepeats()65 int GetNumRepeats() const { return repeats; } 66 HasRepeatsRemaining()67 bool HasRepeatsRemaining() const { 68 return GetNumRepeats() != num_repetitions_done; 69 } 70 71 void DoOneRepetition(); 72 73 RunResults&& GetResults(); 74 GetReportsForFamily()75 BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const { 76 return reports_for_family; 77 } 78 GetMinTime()79 double GetMinTime() const { return min_time; } 80 HasExplicitIters()81 bool HasExplicitIters() const { return has_explicit_iteration_count; } 82 GetIters()83 IterationCount GetIters() const { return iters; } 84 85 private: 86 RunResults run_results; 87 88 const benchmark::internal::BenchmarkInstance& b; 89 BenchmarkReporter::PerFamilyRunReports* reports_for_family; 90 91 BenchTimeType parsed_benchtime_flag; 92 const double min_time; 93 const double min_warmup_time; 94 bool warmup_done; 95 const int repeats; 96 const bool has_explicit_iteration_count; 97 98 int num_repetitions_done = 0; 99 100 std::vector<std::thread> pool; 101 102 std::vector<MemoryManager::Result> memory_results; 103 104 IterationCount iters; // preserved between repetitions! 105 // So only the first repetition has to find/calculate it, 106 // the other repetitions will just use that precomputed iteration count. 107 108 PerfCountersMeasurement* const perf_counters_measurement_ptr = nullptr; 109 110 struct IterationResults { 111 internal::ThreadManager::Result results; 112 IterationCount iters; 113 double seconds; 114 }; 115 IterationResults DoNIterations(); 116 117 MemoryManager::Result* RunMemoryManager(IterationCount memory_iterations); 118 119 void RunProfilerManager(); 120 121 IterationCount PredictNumItersNeeded(const IterationResults& i) const; 122 123 bool ShouldReportIterationResults(const IterationResults& i) const; 124 125 double GetMinTimeToApply() const; 126 127 void FinishWarmUp(const IterationCount& i); 128 129 void RunWarmUp(); 130 }; 131 132 } // namespace internal 133 134 } // end namespace benchmark 135 136 #endif // BENCHMARK_RUNNER_H_ 137