Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: tracing/tracing/metrics/v8/gc_metric.html

Issue 2162963002: [polymer] Merge of master into polymer10-migration (Closed) Base URL: git@github.com:catapult-project/catapult.git@polymer10-migration
Patch Set: Merge polymer10-migration int polymer10-merge Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright 2016 The Chromium Authors. All rights reserved. 3 Copyright 2016 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be 4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file. 5 found in the LICENSE file.
6 --> 6 -->
7 <link rel="import" href="/tracing/base/range.html"> 7 <link rel="import" href="/tracing/base/range.html">
8 <link rel="import" href="/tracing/metrics/metric_registry.html"> 8 <link rel="import" href="/tracing/metrics/metric_registry.html">
9 <link rel="import" href="/tracing/metrics/v8/utils.html"> 9 <link rel="import" href="/tracing/metrics/v8/utils.html">
10 <link rel="import" href="/tracing/value/numeric.html"> 10 <link rel="import" href="/tracing/value/numeric.html">
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 percentile: [] 83 percentile: []
84 }); 84 });
85 return n; 85 return n;
86 } 86 }
87 87
88 function createPercentage(numerator, denominator) { 88 function createPercentage(numerator, denominator) {
89 var percentage = denominator === 0 ? 0 : numerator / denominator * 100; 89 var percentage = denominator === 0 ? 0 : numerator / denominator * 100;
90 return new tr.v.ScalarNumeric(percentage_biggerIsBetter, percentage); 90 return new tr.v.ScalarNumeric(percentage_biggerIsBetter, percentage);
91 } 91 }
92 92
93 function isNotForcedTopGarbageCollectionEvent(event) {
94 // We exclude garbage collection events forced by benchmark runner,
95 // because they cannot happen in real world.
96 return tr.metrics.v8.utils.isTopGarbageCollectionEvent(event) &&
97 !tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);
98 }
99
100 function isNotForcedSubGarbageCollectionEvent(event) {
101 // We exclude garbage collection events forced by benchmark runner,
102 // because they cannot happen in real world.
103 return tr.metrics.v8.utils.isSubGarbageCollectionEvent(event) &&
104 !tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);
105 }
106
93 /** 107 /**
94 * Example output: 108 * Example output:
95 * - Animation-v8_gc_full_mark_compactor. 109 * - v8-gc-full-mark-compactor.
96 */ 110 */
97 function addDurationOfTopEvents(values, model) { 111 function addDurationOfTopEvents(values, model) {
98 groupAndProcessEvents(model, 112 tr.metrics.v8.utils.groupAndProcessEvents(model,
99 tr.metrics.v8.utils.isTopGarbageCollectionEvent, 113 isNotForcedTopGarbageCollectionEvent,
100 tr.metrics.v8.utils.topGarbageCollectionEventName, 114 tr.metrics.v8.utils.topGarbageCollectionEventName,
101 function(stageTitle, name, events) { 115 function(name, events) {
102 var cpuDuration = createNumericForTopEventTime(); 116 var cpuDuration = createNumericForTopEventTime();
103 events.forEach(function(event) { 117 events.forEach(function(event) {
104 cpuDuration.add(event.cpuDuration); 118 cpuDuration.add(event.cpuDuration);
105 }); 119 });
106 values.addValue(new tr.v.NumericValue( 120 values.addValue(new tr.v.NumericValue(name, cpuDuration));
107 stageTitle + '-' + name, cpuDuration));
108 } 121 }
109 ); 122 );
110 } 123 }
111 124
112 /** 125 /**
113 * Example output: 126 * Example output:
114 * - Animation:v8_gc_total 127 * - v8-gc-total
115 */ 128 */
116 function addTotalDurationOfTopEvents(values, model) { 129 function addTotalDurationOfTopEvents(values, model) {
117 groupAndProcessEvents(model, 130 tr.metrics.v8.utils.groupAndProcessEvents(model,
118 tr.metrics.v8.utils.isTopGarbageCollectionEvent, 131 isNotForcedTopGarbageCollectionEvent,
119 event => 'v8-gc-total', 132 event => 'v8-gc-total',
120 function(stageTitle, name, events) { 133 function(name, events) {
121 var cpuDuration = createNumericForTopEventTime(); 134 var cpuDuration = createNumericForTopEventTime();
122 events.forEach(function(event) { 135 events.forEach(function(event) {
123 cpuDuration.add(event.cpuDuration); 136 cpuDuration.add(event.cpuDuration);
124 }); 137 });
125 values.addValue(new tr.v.NumericValue( 138 values.addValue(new tr.v.NumericValue(name, cpuDuration));
126 stageTitle + '-' + name, cpuDuration));
127 } 139 }
128 ); 140 );
129 } 141 }
130 142
131 /** 143 /**
132 * Example output: 144 * Example output:
133 * - Animation-v8-gc-full-mark-compactor-evacuate. 145 * - v8-gc-full-mark-compactor-evacuate.
134 */ 146 */
135 function addDurationOfSubEvents(values, model) { 147 function addDurationOfSubEvents(values, model) {
136 groupAndProcessEvents(model, 148 tr.metrics.v8.utils.groupAndProcessEvents(model,
137 tr.metrics.v8.utils.isSubGarbageCollectionEvent, 149 isNotForcedSubGarbageCollectionEvent,
138 tr.metrics.v8.utils.subGarbageCollectionEventName, 150 tr.metrics.v8.utils.subGarbageCollectionEventName,
139 function(stageTitle, name, events) { 151 function(name, events) {
140 var cpuDuration = createNumericForSubEventTime(); 152 var cpuDuration = createNumericForSubEventTime();
141 events.forEach(function(event) { 153 events.forEach(function(event) {
142 cpuDuration.add(event.cpuDuration); 154 cpuDuration.add(event.cpuDuration);
143 }); 155 });
144 values.addValue(new tr.v.NumericValue( 156 values.addValue(new tr.v.NumericValue(name, cpuDuration));
145 stageTitle + '-' + name, cpuDuration));
146 } 157 }
147 ); 158 );
148 } 159 }
149 160
150 /** 161 /**
151 * Example output: 162 * Example output:
152 * - Animation-v8-gc-full-mark-compactor_idle_deadline_overrun, 163 * - v8-gc-full-mark-compactor_idle_deadline_overrun,
153 * - Animation-v8-gc-full-mark-compactor_outside_idle, 164 * - v8-gc-full-mark-compactor_outside_idle,
154 * - Animation-v8-gc-full-mark-compactor_percentage_idle. 165 * - v8-gc-full-mark-compactor_percentage_idle.
155 */ 166 */
156 function addIdleTimesOfTopEvents(values, model) { 167 function addIdleTimesOfTopEvents(values, model) {
157 groupAndProcessEvents(model, 168 tr.metrics.v8.utils.groupAndProcessEvents(model,
158 tr.metrics.v8.utils.isTopGarbageCollectionEvent, 169 isNotForcedTopGarbageCollectionEvent,
159 tr.metrics.v8.utils.topGarbageCollectionEventName, 170 tr.metrics.v8.utils.topGarbageCollectionEventName,
160 function(stageTitle, name, events) { 171 function(name, events) {
161 addIdleTimes(values, model, stageTitle, name, events); 172 addIdleTimes(values, model, name, events);
162 } 173 }
163 ); 174 );
164 } 175 }
165 176
166 /** 177 /**
167 * Example output: 178 * Example output:
168 * - Animation-v8-gc-total_idle_deadline_overrun, 179 * - v8-gc-total_idle_deadline_overrun,
169 * - Animation-v8-gc-total_outside_idle, 180 * - v8-gc-total_outside_idle,
170 * - Animation-v8-gc-total_percentage_idle. 181 * - v8-gc-total_percentage_idle.
171 */ 182 */
172 function addTotalIdleTimesOfTopEvents(values, model) { 183 function addTotalIdleTimesOfTopEvents(values, model) {
173 groupAndProcessEvents(model, 184 tr.metrics.v8.utils.groupAndProcessEvents(model,
174 tr.metrics.v8.utils.isTopGarbageCollectionEvent, 185 isNotForcedTopGarbageCollectionEvent,
175 event => 'v8-gc-total', 186 event => 'v8-gc-total',
176 function(stageTitle, name, events) { 187 function(name, events) {
177 addIdleTimes(values, model, stageTitle, name, events); 188 addIdleTimes(values, model, name, events);
178 } 189 }
179 ); 190 );
180 } 191 }
181 192
182 function addIdleTimes(values, model, stageTitle, name, events) { 193 function addIdleTimes(values, model, name, events) {
183 var cpuDuration = createNumericForIdleTime(); 194 var cpuDuration = createNumericForIdleTime();
184 var insideIdle = createNumericForIdleTime(); 195 var insideIdle = createNumericForIdleTime();
185 var outsideIdle = createNumericForIdleTime(); 196 var outsideIdle = createNumericForIdleTime();
186 var idleDeadlineOverrun = createNumericForIdleTime(); 197 var idleDeadlineOverrun = createNumericForIdleTime();
187 events.forEach(function(event) { 198 events.forEach(function(event) {
188 var idleTask = tr.metrics.v8.utils.findParent( 199 var idleTask = tr.metrics.v8.utils.findParent(
189 event, tr.metrics.v8.utils.isIdleTask); 200 event, tr.metrics.v8.utils.isIdleTask);
190 var inside = 0; 201 var inside = 0;
191 var overrun = 0; 202 var overrun = 0;
192 if (idleTask) { 203 if (idleTask) {
193 var allottedTime = idleTask['args']['allotted_time_ms']; 204 var allottedTime = idleTask['args']['allotted_time_ms'];
194 if (event.duration > allottedTime) { 205 if (event.duration > allottedTime) {
195 overrun = event.duration - allottedTime; 206 overrun = event.duration - allottedTime;
196 // Don't count time over the deadline as being inside idle time. 207 // Don't count time over the deadline as being inside idle time.
197 // Since the deadline should be relative to wall clock we 208 // Since the deadline should be relative to wall clock we
198 // compare allotted_time_ms with wall duration instead of thread 209 // compare allotted_time_ms with wall duration instead of thread
199 // duration, and then assume the thread duration was inside idle 210 // duration, and then assume the thread duration was inside idle
200 // for the same percentage of time. 211 // for the same percentage of time.
201 inside = event.cpuDuration * allottedTime / event.duration; 212 inside = event.cpuDuration * allottedTime / event.duration;
202 } else { 213 } else {
203 inside = event.cpuDuration; 214 inside = event.cpuDuration;
204 } 215 }
205 } 216 }
206 cpuDuration.add(event.cpuDuration); 217 cpuDuration.add(event.cpuDuration);
207 insideIdle.add(inside); 218 insideIdle.add(inside);
208 outsideIdle.add(event.cpuDuration - inside); 219 outsideIdle.add(event.cpuDuration - inside);
209 idleDeadlineOverrun.add(overrun); 220 idleDeadlineOverrun.add(overrun);
210 }); 221 });
211 values.addValue(new tr.v.NumericValue( 222 values.addValue(new tr.v.NumericValue(
212 stageTitle + '-' + name + '_idle_deadline_overrun', 223 name + '_idle_deadline_overrun',
213 idleDeadlineOverrun)); 224 idleDeadlineOverrun));
214 values.addValue(new tr.v.NumericValue( 225 values.addValue(new tr.v.NumericValue(
215 stageTitle + '-' + name + '_outside_idle', outsideIdle)); 226 name + '_outside_idle', outsideIdle));
216 var percentage = createPercentage(insideIdle.sum, 227 var percentage = createPercentage(insideIdle.sum,
217 cpuDuration.sum); 228 cpuDuration.sum);
218 values.addValue(new tr.v.NumericValue( 229 values.addValue(new tr.v.NumericValue(
219 stageTitle + '-' + name + '_percentage_idle', percentage)); 230 name + '_percentage_idle', percentage));
220 } 231 }
221 232
222 function addV8ExecuteMutatorUtilization(values, model) { 233 function addV8ExecuteMutatorUtilization(values, model) {
223 groupAndProcessEvents(model, 234 tr.metrics.v8.utils.groupAndProcessEvents(model,
224 tr.metrics.v8.utils.isTopV8ExecuteEvent, 235 tr.metrics.v8.utils.isTopV8ExecuteEvent,
225 event => 'v8-execute', 236 event => 'v8-execute',
226 function(stageTitle, name, events) { 237 function(name, events) {
227 events.sort((a, b) => a.start - b.start); 238 events.sort((a, b) => a.start - b.start);
228 var time = 0; 239 var time = 0;
229 var pauses = []; 240 var pauses = [];
230 // Glue together the v8.execute events and adjust the GC pause 241 // Glue together the v8.execute events and adjust the GC pause
231 // times accordingly. 242 // times accordingly.
232 events.forEach(function(topEvent) { 243 for (var topEvent of events) {
233 topEvent.iterateAllDescendents(function(e) { 244 for (var e of topEvent.enumerateAllDescendents()) {
234 if (tr.metrics.v8.utils.isTopGarbageCollectionEvent(e)) { 245 if (isNotForcedTopGarbageCollectionEvent(e)) {
235 pauses.push({ start: e.start - topEvent.start + time, 246 pauses.push({ start: e.start - topEvent.start + time,
236 end: e.end - topEvent.start + time }); 247 end: e.end - topEvent.start + time });
237 } 248 }
238 }); 249 }
239 time += topEvent.duration; 250 time += topEvent.duration;
240 }); 251 }
241 // Now we have one big v8.execute interval from 0 to |time| and 252 // Now we have one big v8.execute interval from 0 to |time| and
242 // a list of GC pauses. 253 // a list of GC pauses.
243 var mutatorUtilization = tr.metrics.v8.utils.mutatorUtilization( 254 var mutatorUtilization = tr.metrics.v8.utils.mutatorUtilization(
244 0, time, WINDOW_SIZE_MS, pauses); 255 0, time, WINDOW_SIZE_MS, pauses);
245 [0.90, 0.95, 0.99].forEach(function(percent) { 256 [0.90, 0.95, 0.99].forEach(function(percent) {
246 var value = new tr.v.ScalarNumeric(percentage_biggerIsBetter, 257 var value = new tr.v.ScalarNumeric(percentage_biggerIsBetter,
247 mutatorUtilization.percentile(1.0 - percent) * 100); 258 mutatorUtilization.percentile(1.0 - percent) * 100);
248 values.addValue(new tr.v.NumericValue( 259 values.addValue(new tr.v.NumericValue(
249 stageTitle + '-v8-execute-mutator-utilization_pct_0' + 260 'v8-execute-mutator-utilization_pct_0' +
250 percent * 100, 261 percent * 100,
251 value)); 262 value));
252 }); 263 });
253 var value = new tr.v.ScalarNumeric(percentage_biggerIsBetter, 264 var value = new tr.v.ScalarNumeric(percentage_biggerIsBetter,
254 mutatorUtilization.min); 265 mutatorUtilization.min);
255 values.addValue(new tr.v.NumericValue( 266 values.addValue(new tr.v.NumericValue(
256 stageTitle + '-v8-execute-mutator-utilization_min', value)); 267 'v8-execute-mutator-utilization_min', value));
257 } 268 }
258 ); 269 );
259 } 270 }
260 271
261 /**
262 * Filters events using the |filterCallback|, then groups events by the user
263 * expectation stage title and the name computed using the |nameCallback|,
264 * and then invokes the |processCallback| with the grouped events.
265 * @param {Function} filterCallback Takes an event and returns a boolean.
266 * @param {Function} nameCallback Takes event and returns a string.
267 * @param {Function} processCallback Takes a stage title, a name, and
268 * an array of events.
269 */
270 function groupAndProcessEvents(model, filterCallback,
271 nameCallback, processCallback) {
272 // Two level map: stageTitle -> name -> [events].
273 var stageTitleToNameToEvents = {};
274 model.userModel.expectations.forEach(function(ue) {
275 stageTitleToNameToEvents[ue.stageTitle] =
276 stageTitleToNameToEvents[ue.stageTitle] || {};
277 var nameToEvents = stageTitleToNameToEvents[ue.stageTitle];
278 ue.associatedEvents.forEach(function(event) {
279 if (!filterCallback(event)) return;
280 var name = nameCallback(event);
281 nameToEvents[name] = nameToEvents[name] || [];
282 nameToEvents[name].push(event);
283 });
284 });
285 tr.b.iterItems(stageTitleToNameToEvents,
286 function(stageTitle, nameToEvents) {
287 tr.b.iterItems(nameToEvents, function(name, events) {
288 processCallback(stageTitle, name, events);
289 });
290 }
291 );
292 }
293
294 return { 272 return {
295 gcMetric: gcMetric, 273 gcMetric: gcMetric,
296 WINDOW_SIZE_MS: WINDOW_SIZE_MS // For testing purposes only. 274 WINDOW_SIZE_MS: WINDOW_SIZE_MS // For testing purposes only.
297 }; 275 };
298 }); 276 });
299 </script> 277 </script>
OLDNEW
« no previous file with comments | « tracing/tracing/metrics/v8/execution_metric.html ('k') | tracing/tracing/metrics/v8/gc_metric_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698