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 26namespace benchmark { 27 28BM_DECLARE_string(benchmark_min_time); 29BM_DECLARE_double(benchmark_min_warmup_time); 30BM_DECLARE_int32(benchmark_repetitions); 31BM_DECLARE_bool(benchmark_report_aggregates_only); 32BM_DECLARE_bool(benchmark_display_aggregates_only); 33BM_DECLARE_string(benchmark_perf_counters); 34 35namespace internal { 36 37extern MemoryManager* memory_manager; 38 39struct 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 47struct BENCHMARK_EXPORT BenchTimeType { 48 enum { ITERS, TIME } tag; 49 union { 50 IterationCount iters; 51 double time; 52 }; 53}; 54 55BENCHMARK_EXPORT 56BenchTimeType ParseBenchMinTime(const std::string& value); 57 58class BenchmarkRunner { 59 public: 60 BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_, 61 benchmark::internal::PerfCountersMeasurement* pmc_, 62 BenchmarkReporter::PerFamilyRunReports* reports_for_family); 63 64 int GetNumRepeats() const { return repeats; } 65 66 bool HasRepeatsRemaining() const { 67 return GetNumRepeats() != num_repetitions_done; 68 } 69 70 void DoOneRepetition(); 71 72 RunResults&& GetResults(); 73 74 BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const { 75 return reports_for_family; 76 } 77 78 double GetMinTime() const { return min_time; } 79 80 bool HasExplicitIters() const { return has_explicit_iteration_count; } 81 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