10000 Merge 7406c890b9181fbb79a1525a81fc30685ea60879 into eb8cbec0776455463… · google/benchmark@c356a2f · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit c356a2f

Browse files
authored
Merge 7406c89 into eb8cbec
2 parents eb8cbec + 7406c89 commit c356a2f

File tree

4 files changed

+411
-225
lines changed

4 files changed

+411
-225
lines changed

src/benchmark.cc

Lines changed: 4 additions & 225 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "benchmark/benchmark.h"
1616
#include "benchmark_api_internal.h"
17+
#include "benchmark_runner.h"
1718
#include "internal_macros.h"
1819

1920
#ifndef BENCHMARK_OS_WINDOWS
@@ -113,230 +114,6 @@ DEFINE_int32(v, 0, "The level of verbose logging to output");
113114

114115
namespace benchmark {
115116

116-
namespace {
117-
static const size_t kMaxIterations = 1000000000;
118-
119-
static MemoryManager* memory_manager = nullptr;
120-
} // end namespace
121-
122-
namespace internal {
123-
124-
void UseCharPointer(char const volatile*) {}
125-
126-
namespace {
127-
128-
BenchmarkReporter::Run CreateRunReport(
129-
const benchmark::internal::Benchmark::Instance& b,
130-
const internal::ThreadManager::Result& results, size_t memory_iterations,
131-
const MemoryManager::Result& memory_result, double seconds) {
132-
// Create report about this benchmark run.
133-
BenchmarkReporter::Run report;
134-
135-
report.run_name = b.name;
136-
report.error_occurred = results.has_error_;
137-
report.error_message = results.error_message_;
138-
report.report_label = results.report_label_;
139-
// This is the total iterations across all threads.
140-
report.iterations = results.iterations;
141-
report.time_unit = b.time_unit;
142-
143-
if (!report.error_occurred) {
144-
if (b.use_manual_time) {
145-
report.real_accumulated_time = results.manual_time_used;
146-
} else {
147-
report.real_accumulated_time = results.real_time_used;
148-
}
149-
report.cpu_accumulated_time = results.cpu_time_used;
150-
report.complexity_n = results.complexity_n;
151-
report.complexity = b.complexity;
152-
report.complexity_lambda = b.complexity_lambda;
153-
report.statistics = b.statistics;
154-
report.counters = results.counters;
155-
156-
if (memory_iterations > 0) {
157-
report.has_memory_result = true;
158-
report.allocs_per_iter =
159-
memory_iterations ? static_cast<double>(memory_result.num_allocs) /
160-
memory_iterations
161-
: 0;
162-
report.max_bytes_used = memory_result.max_bytes_used;
163-
}
164-
165-
internal::Finish(&report.counters, results.iterations, seconds, b.threads);
166-
}
167-
return report;
168-
}
169-
170-
// Execute one thread of benchmark b for the specified number of iterations.
171-
// Adds the stats collected for the thread into *total.
172-
void RunInThread(const benchmark::internal::Benchmark::Instance* b,
173-
size_t iters, int thread_id,
174-
internal::ThreadManager* manager) {
175-
internal::ThreadTimer timer;
176-
State st(iters, b->arg, thread_id, b->threads, &timer, manager);
177-
b->benchmark->Run(st);
178-
CHECK(st.iterations() >= st.max_iterations)
179-
<< "Benchmark returned before State::KeepRunning() returned false!";
180-
{
181-
MutexLock l(manager->GetBenchmarkMutex());
182-
internal::ThreadManager::Result& results = manager->results;
183-
results.iterations += st.iterations();
184-
results.cpu_time_used += timer.cpu_time_used();
185-
results.real_time_used += timer.real_time_used();
186-
results.manual_time_used += timer.manual_time_used();
187-
results.complexity_n += st.complexity_length_n();
188-
internal::Increment(&results.counters, st.counters);
189-
}
190-
manager->NotifyThreadComplete();
191-
}
192-
193-
struct RunResults {
194-
std::vector<BenchmarkReporter::Run> non_aggregates;
195-
std::vector<BenchmarkReporter::Run> aggregates_only;
196-
197-
bool display_report_aggregates_only = false;
198-
bool file_report_aggregates_only = false;
199-
};
200-
201-
RunResults RunBenchmark(
202-
const benchmark::internal::Benchmark::Instance& b,
203-
std::vector<BenchmarkReporter::Run>* complexity_reports) {
204-
RunResults run_results;
205-
206-
const bool has_explicit_iteration_count = b.iterations != 0;
207-
size_t iters = has_explicit_iteration_count ? b.iterations : 1;
208-
std::unique_ptr<internal::ThreadManager> manager;
209-
std::vector<std::thread> pool(b.threads - 1);
210-
const int repeats =
211-
b.repetitions != 0 ? b.repetitions : FLAGS_benchmark_repetitions;
212-
if (repeats != 1) {
213-
run_results.display_report_aggregates_only =
214-
(FLAGS_benchmark_report_aggregates_only ||
215-
FLAGS_benchmark_display_aggregates_only);
216-
run_results.file_report_aggregates_only =
217-
FLAGS_benchmark_report_aggregates_only;
218-
if (b.aggregation_report_mode != internal::ARM_Unspecified) {
219-
run_results.display_report_aggregates_only =
220-
(b.aggregation_report_mode &
221-
internal::ARM_DisplayReportAggregatesOnly);
222-
run_results.file_report_aggregates_only =
223-
(b.aggregation_report_mode & internal::ARM_FileReportAggregatesOnly);
224-
}
225-
}
226-
for (int repetition_num = 0; repetition_num < repeats; repetition_num++) {
227-
for (;;) {
228-
// Try benchmark
229-
VLOG(2) << "Running " << b.name << " for " << iters << "\n";
230-
231-
manager.reset(new internal::ThreadManager(b.threads));
232-
for (std::size_t ti = 0; ti < pool.size(); ++ti) {
233-
pool[ti] = std::thread(&RunInThread, &b, iters,
234-
static_cast<int>(ti + 1), manager.get());
235-
}
236-
RunInThread(&b, iters, 0, manager.get());
237-
manager->WaitForAllThreads();
238-
for (std::thread& thread : pool) thread.join();
239-
internal::ThreadManager::Result results;
240-
{
241-
MutexLock l(manager->GetBenchmarkMutex());
242-
results = manager->results;
243-
}
244-
manager.reset();
245-
// Adjust real/manual time stats since they were reported per thread.
246-
results.real_time_used /= b.threads;
247-
results.manual_time_used /= b.threads;
248-
249-
VLOG(2) << "Ran in " << results.cpu_time_used << "/"
250-
<< results.real_time_used << "\n";
251-
252-
// Base decisions off of real time if requested by this benchmark.
253-
double seconds = results.cpu_time_used;
254-
if (b.use_manual_time) {
255-
seconds = results.manual_time_used;
256-
} else if (b.use_real_time) {
257-
seconds = results.real_time_used;
258-
}
259-
260-
const double min_time =
261-
!IsZero(b.min_time) ? b.min_time : FLAGS_benchmark_min_time;
262-
263-
// clang-format off
264-
// turn off clang-format since it mangles prettiness here
265-
// Determine if this run should be reported; Either it has
266-
// run for a sufficient amount of time or because an error was reported.
267-
const bool should_report = repetition_num > 0
268-
|| has_explicit_iteration_count // An exact iteration count was requested
269-
|| results.has_error_
270-
|| iters >= kMaxIterations // No chance to try again, we hit the limit.
271-
|| seconds >= min_time // the elapsed time is large enough
272-
// CPU time is specified but the elapsed real time greatly exceeds the
273-
// minimum time. Note that user provided timers are except from this
274-
// sanity check.
275-
|| ((results.real_time_used >= 5 * min_time) && !b.use_manual_time);
276-
// clang-format on
277-
278-
if (should_report) {
279-
MemoryManager::Result memory_result;
280-
size_t memory_iterations = 0;
281-
if (memory_manager != nullptr) {
282-
// Only run a few iterations to reduce the impact of one-time
283-
// allocations in benchmarks that are not properly managed.
284-
memory_iterations = std::min<size_t>(16, iters);
285-
memory_manager->Start();
286-
manager.reset(new internal::ThreadManager(1));
287-
RunInThread(&b, memory_iterations, 0, manager.get());
288-
manager->WaitForAllThreads();
289-
manager.reset();
290-
291-
memory_manager->Stop(&memory_result);
292-
}
293-
294-
BenchmarkReporter::Run report = CreateRunReport(
295-
b, results, memory_iterations, memory_result, seconds);
296-
if (!report.error_occurred && b.complexity != oNone)
297-
complexity_reports->push_back(report);
298-
run_results.non_aggregates.push_back(report);
299-
break;
300-
}
301-
302-
// See how much iterations should be increased by
303-
// Note: Avoid division by zero with max(seconds, 1ns).
304-
double multiplier = min_time * 1.4 / std::max(seconds, 1e-9);
305-
// If our last run was at least 10% of FLAGS_benchmark_min_time then we
306-
// use the multiplier directly. Otherwise we use at most 10 times
307-
// expansion.
308-
// NOTE: When the last run was at least 10% of the min time the max
309-
// expansion should be 14x.
310-
bool is_significant = (seconds / min_time) > 0.1;
311-
multiplier = is_significant ? multiplier : std::min(10.0, multiplier);
312-
if (multiplier <= 1.0) multiplier = 2.0;
313-
double next_iters = std::max(multiplier * iters, iters + 1.0);
314-
if (next_iters > kMaxIterations) {
315-
next_iters = kMaxIterations;
316-
}
317-
VLOG(3) << "Next iters: " << next_iters << ", " << multiplier << "\n";
318-
iters = static_cast<int>(next_iters + 0.5);
319-
}
320-
}
321-
322-
// Calculate additional statistics
323-
run_results.aggregates_only = ComputeStats(run_results.non_aggregates);
324-
325-
// Maybe calculate complexity report
326-
if ((b.complexity != oNone) && b.last_benchmark_instance) {
327-
auto additional_run_stats = ComputeBigO(*complexity_reports);
328-
run_results.aggregates_only.insert(run_results.aggregates_only.end(),
329-
additional_run_stats.begin(),
330-
additional_run_stats.end());
331-
complexity_reports->clear();
332-
}
333-
334-
return run_results;
335-
}
336-
337-
} // namespace
338-
} // namespace internal
339-
340117
State::State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
341118
int n_threads, internal::ThreadTimer* timer,
342119
internal::ThreadManager* manager)
@@ -612,7 +389,9 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
612389
return benchmarks.size();
613390
}
614391

615-
void RegisterMemoryManager(MemoryManager* manager) { memory_manager = manager; }
392+
void RegisterMemoryManager(MemoryManager* manager) {
393+
internal::memory_manager = manager;
394+
}
616395

617396
namespace internal {
618397

src/benchmark_api_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define BENCHMARK_API_INTERNAL_H
33

44
#include "benchmark/benchmark.h"
5+
#include "commandlineflags.h"
56

67
#include <cmath>
78
#include <iosfwd>

0 commit comments

Comments
 (0)
0