Skip to content

Commit 0d3243d

Browse files
authored
Merge fa67a07 into a9beffd
2 parents a9beffd + fa67a07 commit 0d3243d

3 files changed

Lines changed: 134 additions & 109 deletions

File tree

src/benchmark.cc

Lines changed: 3 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
#include <condition_variable>
3030
#include <cstdio>
3131
#include <cstdlib>
32-
#include <cstring>
3332
#include <fstream>
3433
#include <iostream>
3534
#include <memory>
35+
#include <string>
3636
#include <thread>
3737

3838
#include "check.h"
@@ -46,7 +46,8 @@
4646
#include "re.h"
4747
#include "statistics.h"
4848
#include "string_util.h"
49-
#include "timers.h"
49+
#include "thread_manager.h"
50+
#include "thread_timer.h"
5051

5152
DEFINE_bool(benchmark_list_tests, false,
5253
"Print a list of benchmarks. This option overrides all other "
@@ -110,113 +111,6 @@ namespace internal {
110111

111112
void UseCharPointer(char const volatile*) {}
112113

113-
class ThreadManager {
114-
public:
115-
ThreadManager(int num_threads)
116-
: alive_threads_(num_threads), start_stop_barrier_(num_threads) {}
117-
118-
Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {
119-
return benchmark_mutex_;
120-
}
121-
122-
bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {
123-
return start_stop_barrier_.wait();
124-
}
125-
126-
void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {
127-
start_stop_barrier_.removeThread();
128-
if (--alive_threads_ == 0) {
129-
MutexLock lock(end_cond_mutex_);
130-
end_condition_.notify_all();
131-
}
132-
}
133-
134-
void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {
135-
MutexLock lock(end_cond_mutex_);
136-
end_condition_.wait(lock.native_handle(),
137-
[this]() { return alive_threads_ == 0; });
138-
}
139-
140-
public:
141-
struct Result {
142-
double real_time_used = 0;
143-
double cpu_time_used = 0;
144-
double manual_time_used = 0;
145-
int64_t bytes_processed = 0;
146-
int64_t items_processed = 0;
147-
int complexity_n = 0;
148-
std::string report_label_;
149-
std::string error_message_;
150-
bool has_error_ = false;
151-
UserCounters counters;
152-
};
153-
GUARDED_BY(GetBenchmarkMutex()) Result results;
154-
155-
private:
156-
mutable Mutex benchmark_mutex_;
157-
std::atomic<int> alive_threads_;
158-
Barrier start_stop_barrier_;
159-
Mutex end_cond_mutex_;
160-
Condition end_condition_;
161-
};
162-
163-
// Timer management class
164-
class ThreadTimer {
165-
public:
166-
ThreadTimer() = default;
167-
168-
// Called by each thread
169-
void StartTimer() {
170-
running_ = true;
171-
start_real_time_ = ChronoClockNow();
172-
start_cpu_time_ = ThreadCPUUsage();
173-
}
174-
175-
// Called by each thread
176-
void StopTimer() {
177-
CHECK(running_);
178-
running_ = false;
179-
real_time_used_ += ChronoClockNow() - start_real_time_;
180-
// Floating point error can result in the subtraction producing a negative
181-
// time. Guard against that.
182-
cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
183-
}
184-
185-
// Called by each thread
186-
void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
187-
188-
bool running() const { return running_; }
189-
190-
// REQUIRES: timer is not running
191-
double real_time_used() {
192-
CHECK(!running_);
193-
return real_time_used_;
194-
}
195-
196-
// REQUIRES: timer is not running
197-
double cpu_time_used() {
198-
CHECK(!running_);
199-
return cpu_time_used_;
200-
}
201-
202-
// REQUIRES: timer is not running
203-
double manual_time_used() {
204-
CHECK(!running_);
205-
return manual_time_used_;
206-
}
207-
208-
private:
209-
bool running_ = false; // Is the timer running
210-
double start_real_time_ = 0; // If running_
211-
double start_cpu_time_ = 0; // If running_
212-
213-
// Accumulated time so far (does not contain current slice if running_)
214-
double real_time_used_ = 0;
215-
double cpu_time_used_ = 0;
216-
// Manually set iteration time. User sets this with SetIterationTime(seconds).
217-
double manual_time_used_ = 0;
218-
};
219-
220114
namespace {
221115

222116
BenchmarkReporter::Run CreateRunReport(

src/thread_manager.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#ifndef BENCHMARK_THREAD_MANAGER_H
2+
#define BENCHMARK_THREAD_MANAGER_H
3+
4+
#include "mutex.h"
5+
6+
namespace benchmark {
7+
namespace internal {
8+
9+
class ThreadManager {
10+
public:
11+
ThreadManager(int num_threads)
12+
: alive_threads_(num_threads), start_stop_barrier_(num_threads) {}
13+
14+
Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {
15+
return benchmark_mutex_;
16+
}
17+
18+
bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {
19+
return start_stop_barrier_.wait();
20+
}
21+
22+
void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {
23+
start_stop_barrier_.removeThread();
24+
if (--alive_threads_ == 0) {
25+
MutexLock lock(end_cond_mutex_);
26+
end_condition_.notify_all();
27+
}
28+
}
29+
30+
void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {
31+
MutexLock lock(end_cond_mutex_);
32+
end_condition_.wait(lock.native_handle(),
33+
[this]() { return alive_threads_ == 0; });
34+
}
35+
36+
public:
37+
struct Result {
38+
double real_time_used = 0;
39+
double cpu_time_used = 0;
40+
double manual_time_used = 0;
41+
int64_t bytes_processed = 0;
42+
int64_t items_processed = 0;
43+
int complexity_n = 0;
44+
std::string report_label_;
45+
std::string error_message_;
46+
bool has_error_ = false;
47+
UserCounters counters;
48+
};
49+
GUARDED_BY(GetBenchmarkMutex()) Result results;
50+
51+
private:
52+
mutable Mutex benchmark_mutex_;
53+
std::atomic<int> alive_threads_;
54+
Barrier start_stop_barrier_;
55+
Mutex end_cond_mutex_;
56+
Condition end_condition_;
57+
};
58+
59+
} // namespace internal
60+
} // namespace benchmark
61+
62+
#endif // BENCHMARK_THREAD_MANAGER_H

src/thread_timer.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#ifndef BENCHMARK_THREAD_TIMER_H
2+
#define BENCHMARK_THREAD_TIMER_H
3+
4+
#include "check.h"
5+
#include "timers.h"
6+
7+
namespace benchmark {
8+
namespace internal {
9+
10+
class ThreadTimer {
11+
public:
12+
ThreadTimer() = default;
13+
14+
// Called by each thread
15+
void StartTimer() {
16+
running_ = true;
17+
start_real_time_ = ChronoClockNow();
18+
start_cpu_time_ = ThreadCPUUsage();
19+
}
20+
21+
// Called by each thread
22+
void StopTimer() {
23+
CHECK(running_);
24+
running_ = false;
25+
real_time_used_ += ChronoClockNow() - start_real_time_;
26+
// Floating point error can result in the subtraction producing a negative
27+
// time. Guard against that.
28+
cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
29+
}
30+
31+
// Called by each thread
32+
void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
33+
34+
bool running() const { return running_; }
35+
36+
// REQUIRES: timer is not running
37+
double real_time_used() {
38+
CHECK(!running_);
39+
return real_time_used_;
40+
}
41+
42+
// REQUIRES: timer is not running
43+
double cpu_time_used() {
44+
CHECK(!running_);
45+
return cpu_time_used_;
46+
}
47+
48+
// REQUIRES: timer is not running
49+
double manual_time_used() {
50+
CHECK(!running_);
51+
return manual_time_used_;
52+
}
53+
54+
private:
55+
bool running_ = false; // Is the timer running
56+
double start_real_time_ = 0; // If running_
57+
double start_cpu_time_ = 0; // If running_
58+
59+
// Accumulated time so far (does not contain current slice if running_)
60+
double real_time_used_ = 0;
61+
double cpu_time_used_ = 0;
62+
// Manually set iteration time. User sets this with SetIterationTime(seconds).
63+
double manual_time_used_ = 0;
64+
};
65+
66+
} // namespace internal
67+
} // namespace benchmark
68+
69+
#endif // BENCHMARK_THREAD_TIMER_H

0 commit comments

Comments
 (0)