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.
This commit is contained in:
Eric 2017-10-17 09:40:44 -06:00 committed by Dominic Hamon
parent 2fc2ea0e45
commit a37fc0c48a
2 changed files with 7 additions and 6 deletions

View File

@ -432,7 +432,7 @@ class State {
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
StartKeepRunning();
}
bool const res = total_iterations_++ < max_iterations;
bool const res = --total_iterations_;
if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
FinishKeepRunning();
}
@ -559,7 +559,7 @@ class State {
int range_y() const { return range(1); }
BENCHMARK_ALWAYS_INLINE
size_t iterations() const { return total_iterations_; }
size_t iterations() const { return (max_iterations - total_iterations_) + 1; }
private:
bool started_;

View File

@ -397,7 +397,7 @@ State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
internal::ThreadManager* manager)
: started_(false),
finished_(false),
total_iterations_(0),
total_iterations_(max_iters + 1),
range_(ranges),
bytes_processed_(0),
items_processed_(0),
@ -410,6 +410,7 @@ State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
timer_(timer),
manager_(manager) {
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";
}
@ -434,7 +435,7 @@ void State::SkipWithError(const char* msg) {
manager_->results.has_error_ = true;
}
}
total_iterations_ = max_iterations;
total_iterations_ = 1;
if (timer_->running()) timer_->StopTimer();
}
@ -459,8 +460,8 @@ void State::FinishKeepRunning() {
if (!error_occurred_) {
PauseTiming();
}
// Total iterations now is one greater than max iterations. Fix this.
total_iterations_ = max_iterations;
// Total iterations has now wrapped around zero. Fix this.
total_iterations_ = 1;
finished_ = true;
manager_->StartStopBarrier();
}