Commit a37fc0c4 by Eric Committed by Dominic Hamon

Improve KeepRunning loop performance to be similar to the range-based for. (#460)

This patch improves the performance of the KeepRunning loop in two ways: (A) it removes the dependency on the max_iterations variable, preventing it from being loaded every iteration. (B) it loops to zero, instead of to an upper bound. This allows a single decrement instruction to be used instead of a arithmetic op followed by a comparison.
parent 2fc2ea0e
...@@ -432,7 +432,7 @@ class State { ...@@ -432,7 +432,7 @@ class State {
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) { if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
StartKeepRunning(); StartKeepRunning();
} }
bool const res = total_iterations_++ < max_iterations; bool const res = --total_iterations_;
if (BENCHMARK_BUILTIN_EXPECT(!res, false)) { if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
FinishKeepRunning(); FinishKeepRunning();
} }
...@@ -559,7 +559,7 @@ class State { ...@@ -559,7 +559,7 @@ class State {
int range_y() const { return range(1); } int range_y() const { return range(1); }
BENCHMARK_ALWAYS_INLINE BENCHMARK_ALWAYS_INLINE
size_t iterations() const { return total_iterations_; } size_t iterations() const { return (max_iterations - total_iterations_) + 1; }
private: private:
bool started_; bool started_;
......
...@@ -397,7 +397,7 @@ State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i, ...@@ -397,7 +397,7 @@ State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
internal::ThreadManager* manager) internal::ThreadManager* manager)
: started_(false), : started_(false),
finished_(false), finished_(false),
total_iterations_(0), total_iterations_(max_iters + 1),
range_(ranges), range_(ranges),
bytes_processed_(0), bytes_processed_(0),
items_processed_(0), items_processed_(0),
...@@ -410,6 +410,7 @@ State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i, ...@@ -410,6 +410,7 @@ State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
timer_(timer), timer_(timer),
manager_(manager) { manager_(manager) {
CHECK(max_iterations != 0) << "At least one iteration must be run"; CHECK(max_iterations != 0) << "At least one iteration must be run";
CHECK(total_iterations_ != 0) << "max iterations wrapped around";
CHECK_LT(thread_index, threads) << "thread_index must be less than threads"; CHECK_LT(thread_index, threads) << "thread_index must be less than threads";
} }
...@@ -434,7 +435,7 @@ void State::SkipWithError(const char* msg) { ...@@ -434,7 +435,7 @@ void State::SkipWithError(const char* msg) {
manager_->results.has_error_ = true; manager_->results.has_error_ = true;
} }
} }
total_iterations_ = max_iterations; total_iterations_ = 1;
if (timer_->running()) timer_->StopTimer(); if (timer_->running()) timer_->StopTimer();
} }
...@@ -459,8 +460,8 @@ void State::FinishKeepRunning() { ...@@ -459,8 +460,8 @@ void State::FinishKeepRunning() {
if (!error_occurred_) { if (!error_occurred_) {
PauseTiming(); PauseTiming();
} }
// Total iterations now is one greater than max iterations. Fix this. // Total iterations has now wrapped around zero. Fix this.
total_iterations_ = max_iterations; total_iterations_ = 1;
finished_ = true; finished_ = true;
manager_->StartStopBarrier(); manager_->StartStopBarrier();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment