OLD | NEW |
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 | 7 |
8 <link rel="import" href="/tracing/metrics/system_health/loading_metric.html"> | 8 <link rel="import" href="/tracing/metrics/system_health/loading_metric.html"> |
9 <link rel="import" href="/tracing/value/histogram_set.html"> | 9 <link rel="import" href="/tracing/value/histogram_set.html"> |
10 | 10 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 * 2. The end of the trace | 63 * 2. The end of the trace |
64 * | 64 * |
65 * This function only works when timestamps are from the same renderer. If | 65 * This function only works when timestamps are from the same renderer. If |
66 * windows for multiple renderers need to be computed, the timestamps should | 66 * windows for multiple renderers need to be computed, the timestamps should |
67 * be separated for each renderer and this function should be called | 67 * be separated for each renderer and this function should be called |
68 * separately for each. | 68 * separately for each. |
69 * | 69 * |
70 * @param {!Array.<number>} interactiveTimestamps | 70 * @param {!Array.<number>} interactiveTimestamps |
71 * @param {!Array.<number>} navStartTimestamps | 71 * @param {!Array.<number>} navStartTimestamps |
72 * @param {!number} traceEndTimestamp | 72 * @param {!number} traceEndTimestamp |
73 * @returns {!Array.<tr.b.Range>} | 73 * @returns {!Array.<tr.b.math.Range>} |
74 */ | 74 */ |
75 function getPostInteractiveTaskWindows( | 75 function getPostInteractiveTaskWindows( |
76 interactiveTimestamps, navStartTimestamps, traceEndTimestamp) { | 76 interactiveTimestamps, navStartTimestamps, traceEndTimestamp) { |
77 var navStartTsIndex = 0; | 77 var navStartTsIndex = 0; |
78 var lastTaskWindowEndTs = undefined; | 78 var lastTaskWindowEndTs = undefined; |
79 var taskWindows = []; | 79 var taskWindows = []; |
80 for (var currTTI of interactiveTimestamps) { | 80 for (var currTTI of interactiveTimestamps) { |
81 // Find the first navigation start event after the interactive | 81 // Find the first navigation start event after the interactive |
82 // timestamp. | 82 // timestamp. |
83 while (navStartTsIndex < navStartTimestamps.length && | 83 while (navStartTsIndex < navStartTimestamps.length && |
84 navStartTimestamps[navStartTsIndex] < currTTI) { | 84 navStartTimestamps[navStartTsIndex] < currTTI) { |
85 navStartTsIndex++; | 85 navStartTsIndex++; |
86 } | 86 } |
87 | 87 |
88 var taskWindowEndTs = navStartTsIndex < navStartTimestamps.length ? | 88 var taskWindowEndTs = navStartTsIndex < navStartTimestamps.length ? |
89 navStartTimestamps[navStartTsIndex] : traceEndTimestamp; | 89 navStartTimestamps[navStartTsIndex] : traceEndTimestamp; |
90 | 90 |
91 if (taskWindowEndTs === lastTaskWindowEndTs) { | 91 if (taskWindowEndTs === lastTaskWindowEndTs) { |
92 // This is the case where we have two different interactive timestamps | 92 // This is the case where we have two different interactive timestamps |
93 // with no navigationStart event between them. This is only possible | 93 // with no navigationStart event between them. This is only possible |
94 // when two different pages are sharing the same renderer process (and | 94 // when two different pages are sharing the same renderer process (and |
95 // therefore the same renderer scheduler). We cannot define a proper | 95 // therefore the same renderer scheduler). We cannot define a proper |
96 // task window in this case to calculate Estimated Input Latency. | 96 // task window in this case to calculate Estimated Input Latency. |
97 throw Error('Encountered two consecutive interactive timestamps ' + | 97 throw Error('Encountered two consecutive interactive timestamps ' + |
98 'with no navigationStart between them. ' + | 98 'with no navigationStart between them. ' + |
99 'PostInteractiveTaskWindow is not well defined in this case.'); | 99 'PostInteractiveTaskWindow is not well defined in this case.'); |
100 } | 100 } |
101 | 101 |
102 taskWindows.push(tr.b.Range.fromExplicitRange( | 102 taskWindows.push(tr.b.math.Range.fromExplicitRange( |
103 currTTI, taskWindowEndTs)); | 103 currTTI, taskWindowEndTs)); |
104 lastTaskWindowEndTs = taskWindowEndTs; | 104 lastTaskWindowEndTs = taskWindowEndTs; |
105 } | 105 } |
106 return taskWindows; | 106 return taskWindows; |
107 } | 107 } |
108 | 108 |
109 /** | 109 /** |
110 * Returns the contribution of the given task to expected queueing time | 110 * Returns the contribution of the given task to expected queueing time |
111 * in the given time window. | 111 * in the given time window. |
112 * | 112 * |
113 * The result is probabilityOf(task) * expectedQueueTimeDueTo(task), | 113 * The result is probabilityOf(task) * expectedQueueTimeDueTo(task), |
114 * where | 114 * where |
115 * - probabilityOf(task) = probability of input arriving while the given | 115 * - probabilityOf(task) = probability of input arriving while the given |
116 * task is running. | 116 * task is running. |
117 * - expectedQueueingTimeDueTo(task) = expected time until the end of the | 117 * - expectedQueueingTimeDueTo(task) = expected time until the end of the |
118 * given task for input arriving while the task is running. | 118 * given task for input arriving while the task is running. |
119 * | 119 * |
120 * We assume that input arrival time is uniformly distributed in the given | 120 * We assume that input arrival time is uniformly distributed in the given |
121 * time window. | 121 * time window. |
122 * | 122 * |
123 * @param {!tr.b.Range} A time window. | 123 * @param {!tr.b.math.Range} A time window. |
124 * @param {!Array.<!{start: number, end: number, weight: number}>} A list of | 124 * @param {!Array.<!{start: number, end: number, weight: number}>} A list of |
125 * weighted tasks. The weight of a task must be between 0.0 and 1.0. | 125 * weighted tasks. The weight of a task must be between 0.0 and 1.0. |
126 * @returns {number} | 126 * @returns {number} |
127 */ | 127 */ |
128 function contributionToEQT(window, task) { | 128 function contributionToEQT(window, task) { |
129 var startInWindow = Math.max(window.min, task.start); | 129 var startInWindow = Math.max(window.min, task.start); |
130 var endInWindow = Math.min(window.max, task.end); | 130 var endInWindow = Math.min(window.max, task.end); |
131 var durationInWindow = endInWindow - startInWindow; | 131 var durationInWindow = endInWindow - startInWindow; |
132 if (durationInWindow <= 0) return 0; | 132 if (durationInWindow <= 0) return 0; |
133 var probabilityOfTask = durationInWindow / (window.max - window.min); | 133 var probabilityOfTask = durationInWindow / (window.max - window.min); |
(...skipping 12 matching lines...) Expand all Loading... |
146 * sum(contributionToEQT(window, task) * task.weight) | 146 * sum(contributionToEQT(window, task) * task.weight) |
147 * for all tasks in weightedTasks, where | 147 * for all tasks in weightedTasks, where |
148 * - contributionToEQT is the function defined above. | 148 * - contributionToEQT is the function defined above. |
149 * - task.weight is an arbitrary number between 0.0 and 1.0. This is useful | 149 * - task.weight is an arbitrary number between 0.0 and 1.0. This is useful |
150 * for computing contribution of chrome subcomponents (e.g. GC) to | 150 * for computing contribution of chrome subcomponents (e.g. GC) to |
151 * the expected queueing time for EQT diagnostics. | 151 * the expected queueing time for EQT diagnostics. |
152 * | 152 * |
153 * We assume that input arrival time is uniformly distributed in the given | 153 * We assume that input arrival time is uniformly distributed in the given |
154 * time window. | 154 * time window. |
155 * | 155 * |
156 * @param {!tr.b.Range} A time window. | 156 * @param {!tr.b.math.Range} A time window. |
157 * @param {!Array.<!{start: number, end: number, weight: number}>} A list of | 157 * @param {!Array.<!{start: number, end: number, weight: number}>} A list of |
158 * weighted tasks. The weight of a task must be between 0.0 and 1.0. | 158 * weighted tasks. The weight of a task must be between 0.0 and 1.0. |
159 * @returns {number} | 159 * @returns {number} |
160 */ | 160 */ |
161 function weightedExpectedQueueingTime(window, weightedTasks) { | 161 function weightedExpectedQueueingTime(window, weightedTasks) { |
162 var result = 0; | 162 var result = 0; |
163 for (var task of weightedTasks) { | 163 for (var task of weightedTasks) { |
164 result += contributionToEQT(window, task) * task.weight; | 164 result += contributionToEQT(window, task) * task.weight; |
165 } | 165 } |
166 return result; | 166 return result; |
167 } | 167 } |
168 | 168 |
169 /** | 169 /** |
170 * Returns expected queueing time for the given time window and | 170 * Returns expected queueing time for the given time window and |
171 * the given set of tasks. The tasks must not overlap. | 171 * the given set of tasks. The tasks must not overlap. |
172 * | 172 * |
173 * @param {!tr.b.Range} A time window. | 173 * @param {!tr.b.math.Range} A time window. |
174 * @param {!Array.<!{start: number, end: number}>} A list of tasks. | 174 * @param {!Array.<!{start: number, end: number}>} A list of tasks. |
175 * @returns {number} | 175 * @returns {number} |
176 */ | 176 */ |
177 function expectedQueueingTime(window, tasks) { | 177 function expectedQueueingTime(window, tasks) { |
178 return weightedExpectedQueueingTime(window, tasks.map(function(task) { | 178 return weightedExpectedQueueingTime(window, tasks.map(function(task) { |
179 return { start: task.start, end: task.end, weight: 1 }; | 179 return { start: task.start, end: task.end, weight: 1 }; |
180 })); | 180 })); |
181 } | 181 } |
182 | 182 |
183 /** | 183 /** |
(...skipping 11 matching lines...) Expand all Loading... |
195 constructor(startTime, windowSize, sortedTasks) { | 195 constructor(startTime, windowSize, sortedTasks) { |
196 /** | 196 /** |
197 * @private @const {number} The window size. | 197 * @private @const {number} The window size. |
198 */ | 198 */ |
199 this.windowSize_ = windowSize; | 199 this.windowSize_ = windowSize; |
200 /** | 200 /** |
201 * @private @const {!Array.<!{start: number, end: number}>} The tasks. | 201 * @private @const {!Array.<!{start: number, end: number}>} The tasks. |
202 */ | 202 */ |
203 this.sortedTasks_ = sortedTasks; | 203 this.sortedTasks_ = sortedTasks; |
204 /** | 204 /** |
205 * @private {!tr.b.Range} The endpoints of the sliding window. | 205 * @private {!tr.b.math.Range} The endpoints of the sliding window. |
206 */ | 206 */ |
207 this.range_ = tr.b.Range.fromExplicitRange( | 207 this.range_ = tr.b.math.Range.fromExplicitRange( |
208 startTime, startTime + windowSize); | 208 startTime, startTime + windowSize); |
209 /** | 209 /** |
210 * @private {number} The index of the first task in the sortedTasks that | 210 * @private {number} The index of the first task in the sortedTasks that |
211 * ends after this window starts: | 211 * ends after this window starts: |
212 * this.range_.min < this.sortedTasks_[this.firstTaskIndex_].end. | 212 * this.range_.min < this.sortedTasks_[this.firstTaskIndex_].end. |
213 */ | 213 */ |
214 this.firstTaskIndex_ = | 214 this.firstTaskIndex_ = |
215 sortedTasks.findIndex(task => startTime < task.end); | 215 sortedTasks.findIndex(task => startTime < task.end); |
216 if (this.firstTaskIndex_ === -1) | 216 if (this.firstTaskIndex_ === -1) |
217 this.firstTaskIndex_ = sortedTasks.length; | 217 this.firstTaskIndex_ = sortedTasks.length; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 this.sortedTasks_[this.lastTaskIndex_]); | 251 this.sortedTasks_[this.lastTaskIndex_]); |
252 } | 252 } |
253 return firstTaskEQT + this.innerEQT_ + lastTaskEQT; | 253 return firstTaskEQT + this.innerEQT_ + lastTaskEQT; |
254 } | 254 } |
255 | 255 |
256 /** | 256 /** |
257 * Moves the window to the given time t. | 257 * Moves the window to the given time t. |
258 * @param {number} The time. | 258 * @param {number} The time. |
259 */ | 259 */ |
260 slide(t) { | 260 slide(t) { |
261 this.range_ = tr.b.Range.fromExplicitRange(t, t + this.windowSize_); | 261 this.range_ = tr.b.math.Range.fromExplicitRange(t, t + this.windowSize_); |
262 if (this.firstTaskIndex_ < this.sortedTasks_.length && | 262 if (this.firstTaskIndex_ < this.sortedTasks_.length && |
263 this.sortedTasks_[this.firstTaskIndex_].end <= t) { | 263 this.sortedTasks_[this.firstTaskIndex_].end <= t) { |
264 // The first task moved out of the window. | 264 // The first task moved out of the window. |
265 this.firstTaskIndex_++; | 265 this.firstTaskIndex_++; |
266 if (this.firstTaskIndex_ < this.lastTaskIndex_) { | 266 if (this.firstTaskIndex_ < this.lastTaskIndex_) { |
267 // The new first window was accounted in innerEQT. Undo that. | 267 // The new first window was accounted in innerEQT. Undo that. |
268 this.innerEQT_ -= contributionToEQT(this.range_, | 268 this.innerEQT_ -= contributionToEQT(this.range_, |
269 this.sortedTasks_[this.firstTaskIndex_]); | 269 this.sortedTasks_[this.firstTaskIndex_]); |
270 } | 270 } |
271 } | 271 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 return { | 351 return { |
352 getPostInteractiveTaskWindows, | 352 getPostInteractiveTaskWindows, |
353 getNavStartTimestamps, | 353 getNavStartTimestamps, |
354 getInteractiveTimestamps, | 354 getInteractiveTimestamps, |
355 expectedQueueingTime, | 355 expectedQueueingTime, |
356 maxExpectedQueueingTimeInSlidingWindow, | 356 maxExpectedQueueingTimeInSlidingWindow, |
357 weightedExpectedQueueingTime | 357 weightedExpectedQueueingTime |
358 }; | 358 }; |
359 }); | 359 }); |
360 </script> | 360 </script> |
OLD | NEW |