blob: fc47028afe00d05f746e594cb9c7438c00a96d47 [file] [log] [blame]
Elliott Hughes307f75d2011-10-12 18:04:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_SRC_TIMING_LOGGER_H_
18#define ART_SRC_TIMING_LOGGER_H_
19
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080020#include "utils.h" // For NanoTime.
Elliott Hughes307f75d2011-10-12 18:04:40 -070021
22#include <stdint.h>
Elliott Hughes307f75d2011-10-12 18:04:40 -070023#include <string>
24#include <vector>
25
26namespace art {
27
Mathieu Chartier0325e622012-09-05 14:22:51 -070028class CumulativeLogger;
29
Elliott Hughes307f75d2011-10-12 18:04:40 -070030class TimingLogger {
Elliott Hughesff17f1f2012-01-24 18:12:29 -080031 public:
Mathieu Chartier2b82db42012-11-14 17:29:05 -080032 explicit TimingLogger(const std::string& name, bool precise = false)
Mathieu Chartier357e9be2012-08-01 11:00:14 -070033 : name_(name), precise_(precise) {
Elliott Hughes307f75d2011-10-12 18:04:40 -070034 AddSplit("");
35 }
36
Mathieu Chartier2b82db42012-11-14 17:29:05 -080037 void Reset() {
38 times_.clear();
39 labels_.clear();
40 AddSplit("");
41 }
42
Elliott Hughes307f75d2011-10-12 18:04:40 -070043 void AddSplit(const std::string& label) {
44 times_.push_back(NanoTime());
45 labels_.push_back(label);
46 }
47
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080048 void Dump() const;
Elliott Hughes601a1232012-02-02 17:47:38 -080049
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050 void Dump(std::ostream& os) const;
Elliott Hughes73e66f72012-05-09 09:34:45 -070051
52 uint64_t GetTotalNs() const {
Elliott Hughes601a1232012-02-02 17:47:38 -080053 return times_.back() - times_.front();
Elliott Hughes307f75d2011-10-12 18:04:40 -070054 }
55
Mathieu Chartier0325e622012-09-05 14:22:51 -070056 protected:
Elliott Hughes307f75d2011-10-12 18:04:40 -070057 std::string name_;
Mathieu Chartier357e9be2012-08-01 11:00:14 -070058 bool precise_;
Elliott Hughes307f75d2011-10-12 18:04:40 -070059 std::vector<uint64_t> times_;
60 std::vector<std::string> labels_;
Mathieu Chartier0325e622012-09-05 14:22:51 -070061
62 friend class CumulativeLogger;
63};
64
65class CumulativeLogger {
66 public:
Mathieu Chartier2b82db42012-11-14 17:29:05 -080067 explicit CumulativeLogger(const std::string& name = "", bool precise = false)
Mathieu Chartier0325e622012-09-05 14:22:51 -070068 : name_(name),
Ian Rogers5f5a2c02012-09-17 10:52:08 -070069 precise_(precise) {
70 Reset();
Mathieu Chartier0325e622012-09-05 14:22:51 -070071 }
72
Mathieu Chartier2b82db42012-11-14 17:29:05 -080073 void SetName(const std::string& name) {
74 name_ = name;
75 }
76
Mathieu Chartier0325e622012-09-05 14:22:51 -070077 void Start() {
78 index_ = 0;
79 last_split_ = NanoTime();
80 }
81
82 void End() {
83 iterations_++;
84 }
85
86 void AddSplit(const std::string& label) {
87 uint64_t cur_time = NanoTime();
88 AddPair(label, cur_time - last_split_);
89 last_split_ = cur_time;
90 }
91
92 void Reset() {
Mathieu Chartier0325e622012-09-05 14:22:51 -070093 times_.clear();
94 labels_.clear();
95 times_squared_.clear();
Ian Rogers5f5a2c02012-09-17 10:52:08 -070096 iterations_ = 0;
97 total_time_squared_ = 0;
Mathieu Chartier0325e622012-09-05 14:22:51 -070098 }
99
100 void AddPair(const std::string& label, uint64_t delta_time) {
101 // Convert delta time to microseconds so that we don't overflow our counters.
102 delta_time /= kAdjust;
103 if (index_ >= times_.size()) {
104 times_.push_back(delta_time);
105 times_squared_.push_back(delta_time * delta_time);
106 labels_.push_back(label);
107 } else {
108 times_[index_] += delta_time;
109 times_squared_[index_] += delta_time * delta_time;
110 DCHECK_EQ(labels_[index_], label);
111 }
112 index_++;
113 }
114
115 void AddLogger(const TimingLogger& logger) {
116 DCHECK_EQ(logger.times_.size(), logger.labels_.size());
117 uint64_t total_time = 0;
118 for (size_t i = 1; i < logger.times_.size(); ++i) {
119 const uint64_t delta_time = logger.times_[i] - logger.times_[i - 1];
120 const std::string& label = logger.labels_[i];
121 AddPair(label, delta_time);
122 total_time += delta_time;
123 }
124 total_time /= kAdjust;
125 total_time_squared_ += total_time * total_time;
126 }
127
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128 void Dump() const;
Mathieu Chartier0325e622012-09-05 14:22:51 -0700129
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130 void Dump(std::ostream& os) const;
Mathieu Chartier0325e622012-09-05 14:22:51 -0700131
132 uint64_t GetTotalNs() const {
Mathieu Chartier155dfe92012-10-09 14:24:49 -0700133 return GetTotalTime() * kAdjust;
134 }
135
136 private:
137
138 uint64_t GetTotalTime() const {
Mathieu Chartier0325e622012-09-05 14:22:51 -0700139 uint64_t total = 0;
140 for (size_t i = 0; i < times_.size(); ++i) {
141 total += times_[i];
142 }
143 return total;
144 }
145
Mathieu Chartier0325e622012-09-05 14:22:51 -0700146 static const uint64_t kAdjust = 1000;
147 std::string name_;
148 bool precise_;
149 uint64_t total_time_squared_;
150 std::vector<uint64_t> times_;
151 std::vector<uint64_t> times_squared_;
152 std::vector<std::string> labels_;
153 size_t index_;
154 size_t iterations_;
155 uint64_t last_split_;
Elliott Hughes307f75d2011-10-12 18:04:40 -0700156};
157
158} // namespace art
159
160#endif // ART_SRC_TIMING_LOGGER_H_