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

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

Issue 1908513002: Add mutator utilization metric. (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: Address Ben's comments Created 4 years, 7 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">
11 <link rel="import" href="/tracing/value/unit.html"> 11 <link rel="import" href="/tracing/value/unit.html">
12 <link rel="import" href="/tracing/value/value.html"> 12 <link rel="import" href="/tracing/value/value.html">
13 13
14 <script> 14 <script>
15 'use strict'; 15 'use strict';
16 16
17 tr.exportTo('tr.metrics.v8', function() { 17 tr.exportTo('tr.metrics.v8', function() {
18 // The time window size for mutator utilization computation.
19 // It is equal to the duration of one frame corresponding to 60 FPS rendering.
20 var TARGET_FPS = 60;
21 var MS_PER_SECOND = 1000;
22 var WINDOW_SIZE_MS = MS_PER_SECOND / TARGET_FPS;
23
18 function gcMetric(valueList, model) { 24 function gcMetric(valueList, model) {
19 addDurationOfTopEvents(valueList, model); 25 addDurationOfTopEvents(valueList, model);
20 addTotalDurationOfTopEvents(valueList, model); 26 addTotalDurationOfTopEvents(valueList, model);
21 addDurationOfSubEvents(valueList, model); 27 addDurationOfSubEvents(valueList, model);
22 addIdleTimesOfTopEvents(valueList, model); 28 addIdleTimesOfTopEvents(valueList, model);
23 addTotalIdleTimesOfTopEvents(valueList, model); 29 addTotalIdleTimesOfTopEvents(valueList, model);
30 addMutatorUtilization(valueList, model);
24 } 31 }
25 32
26 gcMetric.prototype = { 33 gcMetric.prototype = {
27 __proto__: Function.prototype 34 __proto__: Function.prototype
28 }; 35 };
29 36
30 tr.metrics.MetricRegistry.register(gcMetric); 37 tr.metrics.MetricRegistry.register(gcMetric);
31 38
32 var timeDurationInMs_smallerIsBetter = 39 var timeDurationInMs_smallerIsBetter =
33 tr.v.Unit.byName.timeDurationInMs_smallerIsBetter; 40 tr.v.Unit.byName.timeDurationInMs_smallerIsBetter;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 var insideIdle = createNumeric(); 159 var insideIdle = createNumeric();
153 var outsideIdle = createNumeric(); 160 var outsideIdle = createNumeric();
154 var idleDeadlineOverrun = createNumeric(); 161 var idleDeadlineOverrun = createNumeric();
155 events.forEach(function(event) { 162 events.forEach(function(event) {
156 var idleTask = tr.metrics.v8.utils.findParent( 163 var idleTask = tr.metrics.v8.utils.findParent(
157 event, tr.metrics.v8.utils.isIdleTask); 164 event, tr.metrics.v8.utils.isIdleTask);
158 var inside = 0; 165 var inside = 0;
159 var overrun = 0; 166 var overrun = 0;
160 if (idleTask) { 167 if (idleTask) {
161 var allottedTime = idleTask['args']['allotted_time_ms']; 168 var allottedTime = idleTask['args']['allotted_time_ms'];
162 console.log(allottedTime);
163 if (event.duration > allottedTime) { 169 if (event.duration > allottedTime) {
164 overrun = event.duration - allottedTime; 170 overrun = event.duration - allottedTime;
165 // Don't count time over the deadline as being inside idle time. 171 // Don't count time over the deadline as being inside idle time.
166 // Since the deadline should be relative to wall clock we 172 // Since the deadline should be relative to wall clock we
167 // compare allotted_time_ms with wall duration instead of thread 173 // compare allotted_time_ms with wall duration instead of thread
168 // duration, and then assume the thread duration was inside idle 174 // duration, and then assume the thread duration was inside idle
169 // for the same percentage of time. 175 // for the same percentage of time.
170 inside = event.cpuDuration * allottedTime / event.duration; 176 inside = event.cpuDuration * allottedTime / event.duration;
171 } else { 177 } else {
172 inside = event.cpuDuration; 178 inside = event.cpuDuration;
(...skipping 11 matching lines...) Expand all
184 valueList.addValue( 190 valueList.addValue(
185 new tr.v.NumericValue(model.canonicalUrl, 191 new tr.v.NumericValue(model.canonicalUrl,
186 stageTitle + '-' + name + '_outside_idle', outsideIdle)); 192 stageTitle + '-' + name + '_outside_idle', outsideIdle));
187 var percentage = createPercentage(insideIdle.runningSum, 193 var percentage = createPercentage(insideIdle.runningSum,
188 cpuDuration.runningSum); 194 cpuDuration.runningSum);
189 valueList.addValue( 195 valueList.addValue(
190 new tr.v.NumericValue(model.canonicalUrl, 196 new tr.v.NumericValue(model.canonicalUrl,
191 stageTitle + '-' + name + '_percentage_idle', percentage)); 197 stageTitle + '-' + name + '_percentage_idle', percentage));
192 } 198 }
193 199
200 function addMutatorUtilization(valueList, model) {
201 groupAndProcessEvents(model,
202 tr.metrics.v8.utils.isTopV8ExecuteEvent,
203 event => 'v8.execute',
204 function(stageTitle, name, events) {
205 events.sort((a, b) => a.start - b.start);
206 var time = 0;
207 var pauses = [];
208 // Glue together the v8.execute events and adjust the GC pause
209 // times accordingly.
210 events.forEach(function(topEvent) {
211 topEvent.findTopmostSlicesRelativeToThisSlice(function(e) {
212 if (tr.metrics.v8.utils.isTopGarbageCollectionEvent(e)) {
213 pauses.push({ start: e.start - topEvent.start + time,
214 end: e.end - topEvent.start + time });
215 }
216 });
217 time += topEvent.duration;
218 });
219 // Now we have one big v8.execute interval from 0 to |time| and
220 // a list of GC pauses.
221 var mutatorUtilization = tr.metrics.v8.utils.mutatorUtilization(
222 0, time, WINDOW_SIZE_MS, pauses);
223 [0.95, 0.99].forEach(function(percent) {
224 var value = new tr.v.ScalarNumeric(percentage_biggerIsBetter,
225 mutatorUtilization.percentile(1.0 - percent) * 100);
226 valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,
227 stageTitle + '-mutator_utilization_pct_0' + percent * 100,
228 value));
229 });
230 var value = new tr.v.ScalarNumeric(percentage_biggerIsBetter,
231 mutatorUtilization.min);
232 valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,
233 stageTitle + '-mutator_utilization_min', value));
234 }
235 );
236 }
237
194 /** 238 /**
195 * Filters events using the |filterCallback|, then groups events by the user 239 * Filters events using the |filterCallback|, then groups events by the user
196 * expectation stage title and the name computed using the |nameCallback|, 240 * expectation stage title and the name computed using the |nameCallback|,
197 * and then invokes the |processCallback| with the grouped events. 241 * and then invokes the |processCallback| with the grouped events.
198 * @param {Function} filterCallback Takes an event and returns a boolean. 242 * @param {Function} filterCallback Takes an event and returns a boolean.
199 * @param {Function} nameCallback Takes event and returns a string. 243 * @param {Function} nameCallback Takes event and returns a string.
200 * @param {Function} processCallback Takes a stage title, a name, and 244 * @param {Function} processCallback Takes a stage title, a name, and
201 * an array of events. 245 * an array of events.
202 */ 246 */
203 function groupAndProcessEvents(model, filterCallback, 247 function groupAndProcessEvents(model, filterCallback,
(...skipping 14 matching lines...) Expand all
218 tr.b.iterItems(stageTitleToNameToEvents, 262 tr.b.iterItems(stageTitleToNameToEvents,
219 function(stageTitle, nameToEvents) { 263 function(stageTitle, nameToEvents) {
220 tr.b.iterItems(nameToEvents, function(name, events) { 264 tr.b.iterItems(nameToEvents, function(name, events) {
221 processCallback(stageTitle, name, events); 265 processCallback(stageTitle, name, events);
222 }); 266 });
223 } 267 }
224 ); 268 );
225 } 269 }
226 270
227 return { 271 return {
228 gcMetric: gcMetric 272 gcMetric: gcMetric,
273 WINDOW_SIZE_MS: WINDOW_SIZE_MS // For testing purposes only.
229 }; 274 };
230 }); 275 });
231 </script> 276 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698