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 | |
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 |