class CumulativeLogger { public: explicit CumulativeLogger(const std::string& name);
~CumulativeLogger(); void Start(); void End() REQUIRES(!GetLock()); void Reset() REQUIRES(!GetLock()); void Dump(std::ostream& os) const REQUIRES(!GetLock());
uint64_t GetTotalNs() const { return GetTotalTime() * kAdjust;
} // Allow the name to be modified, particularly when the cumulative logger is a field within a // parent class that is unable to determine the "name" of a sub-class. void SetName(const std::string& name) REQUIRES(!GetLock()); void AddLogger(const TimingLogger& logger) REQUIRES(!GetLock());
size_t GetIterations() const REQUIRES(!GetLock());
static constexpr uint64_t kAdjust = 1000; // Use a vector to keep dirty memory to minimal number of pages. Using a // hashtable would be performant, but could lead to more dirty pages. Also, we // don't expect this vector to be too big.
std::vector<CumulativeTime> cumulative_timers_ GUARDED_BY(GetLock());
std::string name_; const std::string lock_name_; mutable std::unique_ptr<Mutex> lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
size_t iterations_ GUARDED_BY(GetLock());
uint64_t total_time_;
DISALLOW_COPY_AND_ASSIGN(CumulativeLogger);
};
// A timing logger that knows when a split starts for the purposes of logging tools, like systrace. class TimingLogger { public: static constexpr size_t kIndexNotFound = static_cast<size_t>(-1);
// Kind of timing we are going to do. We collect time at the nano second. enumclass TimingKind {
kMonotonic,
kThreadCpu,
};
// Extra data that is only calculated when you call dump to prevent excess allocation. class TimingData { public:
TimingData() = default;
TimingData(TimingData&& other) noexcept = default;
TimingData& operator=(TimingData&& other) noexcept = default;
uint64_t GetTotalTime(size_t idx) { return data_[idx].total_time;
}
uint64_t GetExclusiveTime(size_t idx) { return data_[idx].exclusive_time;
}
private: // Each begin split has a total time and exclusive time. Exclusive time is total time - total // time of children nodes. struct CalculatedDataPoint {
CalculatedDataPoint() : total_time(0), exclusive_time(0) {}
uint64_t total_time;
uint64_t exclusive_time;
};
std::vector<CalculatedDataPoint> data_; friendclass TimingLogger;
};
EXPORT TimingLogger(constchar* name, bool precise, bool verbose,
TimingKind kind = TimingKind::kMonotonic);
EXPORT ~TimingLogger(); // Verify that all open timings have related closed timings. void Verify(); // Clears current timings and labels. void Reset(); // Starts a timing.
EXPORT void StartTiming(constchar* new_split_label); // Ends the current timing.
EXPORT void EndTiming(); // End the current timing and start a new timing. Usage not recommended. void NewTiming(constchar* new_split_label) {
EndTiming();
StartTiming(new_split_label);
} // Returns the total duration of the timings (sum of total times).
uint64_t GetTotalNs() const; // Find the index of a timing by name.
size_t FindTimingIndex(constchar* name, size_t start_idx) const;
EXPORT void Dump(std::ostream& os, constchar* indent_string = " ") const;
// Scoped timing splits that can be nested and composed with the explicit split // starts and ends. class ScopedTiming { public:
ScopedTiming(constchar* label, TimingLogger* logger) : logger_(logger) {
logger_->StartTiming(label);
}
~ScopedTiming() {
logger_->EndTiming();
} // Closes the current timing and opens a new timing. void NewTiming(constchar* label) {
logger_->NewTiming(label);
}
private:
TimingLogger* const logger_; // The timing logger which the scoped timing is associated with.
DISALLOW_COPY_AND_ASSIGN(ScopedTiming);
};
// Return the time points of when each start / end timings start and finish. const std::vector<Timing>& GetTimings() const { return timings_;
}
TimingData CalculateTimingData() const;
protected: // The name of the timing logger. constchar* const name_; // Do we want to print the exactly recorded split (true) or round down to the time unit being // used (false). constbool precise_; // Verbose logging. constbool verbose_; // The kind of timing we want. const TimingKind kind_; // Timing points that are either start or end points. For each starting point ret[i] = location // of end split associated with i. If it is and end split ret[i] = i.
std::vector<Timing> timings_;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.