summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2012-09-14 13:37:31 (GMT)
committerNico Weber <nicolasweber@gmx.de>2012-09-14 13:48:48 (GMT)
commit48143c9b07eca30c99d47cadf3c0ae111b369f1b (patch)
tree664f292f0ca0797ecb02a5c7df0f5158eb36f51d
parent06fa62352d1e9868409b299ffc8abc8f4cd9a39d (diff)
downloadNinja-48143c9b07eca30c99d47cadf3c0ae111b369f1b.zip
Ninja-48143c9b07eca30c99d47cadf3c0ae111b369f1b.tar.gz
Ninja-48143c9b07eca30c99d47cadf3c0ae111b369f1b.tar.bz2
Change rate measurement code.
For %o, remove a superfluous + 0.5: snprintf("%f") rounds already. Remove some unnecessary code. For %c, fix a TODO to add a sliding window and update after every completed edge. Else, with -j50 and several files that take 3s to compile each, this number would only update every 150s. Also give the number one decimal place so that this can measure steps slower than 1s.
-rw-r--r--src/build.cc24
-rw-r--r--src/build.h58
-rw-r--r--src/metrics.h9
3 files changed, 53 insertions, 38 deletions
diff --git a/src/build.cc b/src/build.cc
index e1aaad1..5a0c3b3 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -42,8 +42,7 @@ BuildStatus::BuildStatus(const BuildConfig& config)
start_time_millis_(GetTimeMillis()),
started_edges_(0), finished_edges_(0), total_edges_(0),
have_blank_line_(true), progress_status_format_(NULL),
- overall_rate_(), current_rate_(),
- current_rate_average_count_(config.parallelism) {
+ overall_rate_(), current_rate_(config.parallelism) {
#ifndef _WIN32
const char* term = getenv("TERM");
smart_terminal_ = isatty(1) && term && string(term) != "dumb";
@@ -136,7 +135,8 @@ void BuildStatus::BuildFinished() {
printf("\n");
}
-string BuildStatus::FormatProgressStatus(const char* progress_status_format) const {
+string BuildStatus::FormatProgressStatus(
+ const char* progress_status_format) const {
string out;
char buf[32];
for (const char* s = progress_status_format; *s != '\0'; ++s) {
@@ -177,30 +177,24 @@ string BuildStatus::FormatProgressStatus(const char* progress_status_format) con
out += buf;
break;
- // Overall finished edges per second.
+ // Overall finished edges per second.
case 'o':
- overall_rate_.UpdateRate(finished_edges_, finished_edges_);
+ overall_rate_.UpdateRate(finished_edges_);
overall_rate_.snprinfRate(buf, "%.1f");
out += buf;
break;
- // Current rate, average over the last '-j' jobs.
+ // Current rate, average over the last '-j' jobs.
case 'c':
- // TODO use sliding window?
- if (finished_edges_ > current_rate_.last_update() &&
- finished_edges_ - current_rate_.last_update() == current_rate_average_count_) {
- current_rate_.UpdateRate(current_rate_average_count_, finished_edges_);
- current_rate_.Restart();
- }
- current_rate_.snprinfRate(buf, "%.0f");
+ current_rate_.UpdateRate(finished_edges_);
+ current_rate_.snprinfRate(buf, "%.1f");
out += buf;
break;
- default: {
+ default:
Fatal("unknown placeholder '%%%c' in $NINJA_STATUS", *s);
return "";
}
- }
} else {
out.push_back(*s);
}
diff --git a/src/build.h b/src/build.h
index 3e7a144..0902a4c 100644
--- a/src/build.h
+++ b/src/build.h
@@ -201,37 +201,59 @@ struct BuildStatus {
const char* progress_status_format_;
struct RateInfo {
- RateInfo() : last_update_(0), rate_(-1) {}
-
- double rate() const { return rate_; }
- int last_update() const { return last_update_; }
- void Restart() { return stopwatch_.Restart(); }
-
- double UpdateRate(int edges, int update_hint) {
- if (update_hint != last_update_) {
- rate_ = edges / stopwatch_.Elapsed() + 0.5;
- last_update_ = update_hint;
- }
- return rate_;
+ RateInfo() : rate_(-1) {}
+
+ void Restart() { stopwatch_.Restart(); }
+
+ void UpdateRate(int edges) {
+ if (edges && stopwatch_.Elapsed())
+ rate_ = edges / stopwatch_.Elapsed();
+ }
+
+ template<class T>
+ void snprinfRate(T buf, const char* format) {
+ if (rate_ == -1) snprintf(buf, sizeof(buf), "?");
+ else snprintf(buf, sizeof(buf), format, rate_);
+ }
+
+ private:
+ Stopwatch stopwatch_;
+ double rate_;
+ };
+
+ struct SlidingRateInfo {
+ SlidingRateInfo(int n) : N(n), last_update_(-1), rate_(-1) {}
+
+ void Restart() { stopwatch_.Restart(); }
+
+ void UpdateRate(int update_hint) {
+ if (update_hint == last_update_)
+ return;
+ last_update_ = update_hint;
+
+ if (times_.size() == N)
+ times_.pop();
+ times_.push(stopwatch_.Elapsed());
+ if (times_.back() != times_.front())
+ rate_ = times_.size() / (times_.back() - times_.front());
}
template<class T>
void snprinfRate(T buf, const char* format) {
- if (rate_ == -1)
- snprintf(buf, sizeof(buf), "?");
- else
- snprintf(buf, sizeof(buf), format, rate_);
+ if (rate_ == -1) snprintf(buf, sizeof(buf), "?");
+ else snprintf(buf, sizeof(buf), format, rate_);
}
private:
+ const size_t N;
+ std::queue<double> times_;
Stopwatch stopwatch_;
int last_update_;
double rate_;
};
mutable RateInfo overall_rate_;
- mutable RateInfo current_rate_;
- const int current_rate_average_count_;
+ mutable SlidingRateInfo current_rate_;
#ifdef _WIN32
void* console_;
diff --git a/src/metrics.h b/src/metrics.h
index f5ac0de..a4ef9f7 100644
--- a/src/metrics.h
+++ b/src/metrics.h
@@ -59,19 +59,18 @@ private:
};
/// Get the current time as relative to some epoch.
-/// Epoch varies between platforms; only useful for measuring elapsed
-/// time.
+/// Epoch varies between platforms; only useful for measuring elapsed time.
int64_t GetTimeMillis();
-/// A simple stopwatch which retruns the time
-// in seconds since Restart() was called
+/// A simple stopwatch which returns the time
+/// in seconds since Restart() was called.
class Stopwatch
{
public:
Stopwatch() : started_(0) {}
- /// Seconds since Restart() call
+ /// Seconds since Restart() call.
double Elapsed() const { return 1e-6 * static_cast<double>(Now() - started_); }
void Restart() { started_ = Now(); }