aboutsummaryrefslogtreecommitdiff
path: root/src/benchmark_runner.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/benchmark_runner.h')
-rw-r--r--src/benchmark_runner.h102
1 files changed, 91 insertions, 11 deletions
diff --git a/src/benchmark_runner.h b/src/benchmark_runner.h
index 96e8282..db2fa04 100644
--- a/src/benchmark_runner.h
+++ b/src/benchmark_runner.h
@@ -15,19 +15,23 @@
#ifndef BENCHMARK_RUNNER_H_
#define BENCHMARK_RUNNER_H_
+#include <thread>
+#include <vector>
+
#include "benchmark_api_internal.h"
#include "internal_macros.h"
-
-DECLARE_double(benchmark_min_time);
-
-DECLARE_int32(benchmark_repetitions);
-
-DECLARE_bool(benchmark_report_aggregates_only);
-
-DECLARE_bool(benchmark_display_aggregates_only);
+#include "perf_counters.h"
+#include "thread_manager.h"
namespace benchmark {
+BM_DECLARE_string(benchmark_min_time);
+BM_DECLARE_double(benchmark_min_warmup_time);
+BM_DECLARE_int32(benchmark_repetitions);
+BM_DECLARE_bool(benchmark_report_aggregates_only);
+BM_DECLARE_bool(benchmark_display_aggregates_only);
+BM_DECLARE_string(benchmark_perf_counters);
+
namespace internal {
extern MemoryManager* memory_manager;
@@ -40,9 +44,85 @@ struct RunResults {
bool file_report_aggregates_only = false;
};
-RunResults RunBenchmark(
- const benchmark::internal::BenchmarkInstance& b,
- std::vector<BenchmarkReporter::Run>* complexity_reports);
+struct BENCHMARK_EXPORT BenchTimeType {
+ enum { ITERS, TIME } tag;
+ union {
+ IterationCount iters;
+ double time;
+ };
+};
+
+BENCHMARK_EXPORT
+BenchTimeType ParseBenchMinTime(const std::string& value);
+
+class BenchmarkRunner {
+ public:
+ BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_,
+ benchmark::internal::PerfCountersMeasurement* pmc_,
+ BenchmarkReporter::PerFamilyRunReports* reports_for_family);
+
+ int GetNumRepeats() const { return repeats; }
+
+ bool HasRepeatsRemaining() const {
+ return GetNumRepeats() != num_repetitions_done;
+ }
+
+ void DoOneRepetition();
+
+ RunResults&& GetResults();
+
+ BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const {
+ return reports_for_family;
+ }
+
+ double GetMinTime() const { return min_time; }
+
+ bool HasExplicitIters() const { return has_explicit_iteration_count; }
+
+ IterationCount GetIters() const { return iters; }
+
+ private:
+ RunResults run_results;
+
+ const benchmark::internal::BenchmarkInstance& b;
+ BenchmarkReporter::PerFamilyRunReports* reports_for_family;
+
+ BenchTimeType parsed_benchtime_flag;
+ const double min_time;
+ const double min_warmup_time;
+ bool warmup_done;
+ const int repeats;
+ const bool has_explicit_iteration_count;
+
+ int num_repetitions_done = 0;
+
+ std::vector<std::thread> pool;
+
+ std::vector<MemoryManager::Result> memory_results;
+
+ IterationCount iters; // preserved between repetitions!
+ // So only the first repetition has to find/calculate it,
+ // the other repetitions will just use that precomputed iteration count.
+
+ PerfCountersMeasurement* const perf_counters_measurement_ptr = nullptr;
+
+ struct IterationResults {
+ internal::ThreadManager::Result results;
+ IterationCount iters;
+ double seconds;
+ };
+ IterationResults DoNIterations();
+
+ IterationCount PredictNumItersNeeded(const IterationResults& i) const;
+
+ bool ShouldReportIterationResults(const IterationResults& i) const;
+
+ double GetMinTimeToApply() const;
+
+ void FinishWarmUp(const IterationCount& i);
+
+ void RunWarmUp();
+};
} // namespace internal