OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 import collections | 4 import collections |
5 from telemetry.util.statistics import DivideIfPossibleOrZero | 5 from telemetry.util.statistics import DivideIfPossibleOrZero |
6 | 6 |
7 from telemetry.web_perf.metrics import timeline_based_metric | 7 from telemetry.web_perf.metrics import timeline_based_metric |
8 from telemetry.value import scalar | 8 from telemetry.value import scalar |
9 | 9 |
10 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 for event_name, event_group in events_by_name.iteritems(): | 40 for event_name, event_group in events_by_name.iteritems(): |
41 times = [event.self_time for event in event_group] | 41 times = [event.self_time for event in event_group] |
42 total = sum(times) | 42 total = sum(times) |
43 biggest_jank = max(times) | 43 biggest_jank = max(times) |
44 | 44 |
45 # Results objects cannot contain the '.' character, so remove that here. | 45 # Results objects cannot contain the '.' character, so remove that here. |
46 sanitized_event_name = event_name.replace('.', '_') | 46 sanitized_event_name = event_name.replace('.', '_') |
47 | 47 |
48 full_name = thread_name + '|' + sanitized_event_name | 48 full_name = thread_name + '|' + sanitized_event_name |
49 results.AddValue(scalar.ScalarValue( | 49 results.AddValue(scalar.ScalarValue( |
50 results.current_page, full_name, 'ms', total)) | 50 results.current_page, full_name, 'ms', total, |
| 51 higher_is_better=False)) |
51 results.AddValue(scalar.ScalarValue( | 52 results.AddValue(scalar.ScalarValue( |
52 results.current_page, full_name + '_max', 'ms', biggest_jank)) | 53 results.current_page, full_name + '_max', 'ms', biggest_jank, |
| 54 higher_is_better=False)) |
53 results.AddValue(scalar.ScalarValue( | 55 results.AddValue(scalar.ScalarValue( |
54 results.current_page, full_name + '_avg', 'ms', total / len(times))) | 56 results.current_page, full_name + '_avg', 'ms', total / len(times), |
| 57 higher_is_better=False)) |
55 | 58 |
56 for counter_name, counter in renderer_process.counters.iteritems(): | 59 for counter_name, counter in renderer_process.counters.iteritems(): |
57 total = sum(counter.totals) | 60 total = sum(counter.totals) |
58 | 61 |
59 # Results objects cannot contain the '.' character, so remove that here. | 62 # Results objects cannot contain the '.' character, so remove that here. |
60 sanitized_counter_name = counter_name.replace('.', '_') | 63 sanitized_counter_name = counter_name.replace('.', '_') |
61 | 64 |
62 results.AddValue(scalar.ScalarValue( | 65 results.AddValue(scalar.ScalarValue( |
63 results.current_page, sanitized_counter_name, 'count', total)) | 66 results.current_page, sanitized_counter_name, 'count', total, |
| 67 higher_is_better=False)) |
64 results.AddValue(scalar.ScalarValue( | 68 results.AddValue(scalar.ScalarValue( |
65 results.current_page, sanitized_counter_name + '_avg', 'count', | 69 results.current_page, sanitized_counter_name + '_avg', 'count', |
66 total / float(len(counter.totals)))) | 70 total / float(len(counter.totals)), higher_is_better=False)) |
67 | 71 |
68 # We want to generate a consistant picture of our thread usage, despite | 72 # We want to generate a consistant picture of our thread usage, despite |
69 # having several process configurations (in-proc-gpu/single-proc). | 73 # having several process configurations (in-proc-gpu/single-proc). |
70 # Since we can't isolate renderer threads in single-process mode, we | 74 # Since we can't isolate renderer threads in single-process mode, we |
71 # always sum renderer-process threads' times. We also sum all io-threads | 75 # always sum renderer-process threads' times. We also sum all io-threads |
72 # for simplicity. | 76 # for simplicity. |
73 TimelineThreadCategories = { | 77 TimelineThreadCategories = { |
74 "Chrome_InProcGpuThread": "GPU", | 78 "Chrome_InProcGpuThread": "GPU", |
75 "CrGpuMain" : "GPU", | 79 "CrGpuMain" : "GPU", |
76 "AsyncTransferThread" : "GPU_transfer", | 80 "AsyncTransferThread" : "GPU_transfer", |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 self.all_slices.extend(self.SlicesInActions(thread.all_slices)) | 192 self.all_slices.extend(self.SlicesInActions(thread.all_slices)) |
189 self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices)) | 193 self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices)) |
190 | 194 |
191 # Currently we report cpu-time per frame, tasks per frame, and possibly | 195 # Currently we report cpu-time per frame, tasks per frame, and possibly |
192 # the mean frame (if there is a trace specified to find it). | 196 # the mean frame (if there is a trace specified to find it). |
193 def AddResults(self, num_frames, results): | 197 def AddResults(self, num_frames, results): |
194 cpu_per_frame = Rate(self.cpu_time, num_frames) | 198 cpu_per_frame = Rate(self.cpu_time, num_frames) |
195 tasks_per_frame = Rate(len(self.toplevel_slices), num_frames) | 199 tasks_per_frame = Rate(len(self.toplevel_slices), num_frames) |
196 results.AddValue(scalar.ScalarValue( | 200 results.AddValue(scalar.ScalarValue( |
197 results.current_page, ThreadCpuTimeResultName(self.name), | 201 results.current_page, ThreadCpuTimeResultName(self.name), |
198 'ms', cpu_per_frame)) | 202 'ms', cpu_per_frame, higher_is_better=False)) |
199 results.AddValue(scalar.ScalarValue( | 203 results.AddValue(scalar.ScalarValue( |
200 results.current_page, ThreadTasksResultName(self.name), | 204 results.current_page, ThreadTasksResultName(self.name), |
201 'tasks', tasks_per_frame)) | 205 'tasks', tasks_per_frame, higher_is_better=False)) |
202 # Report mean frame time if this is the thread we are using for normalizing | 206 # Report mean frame time if this is the thread we are using for normalizing |
203 # other results. We could report other frame rates (eg. renderer_main) but | 207 # other results. We could report other frame rates (eg. renderer_main) but |
204 # this might get confusing. | 208 # this might get confusing. |
205 if self.name == FrameTraceThreadName: | 209 if self.name == FrameTraceThreadName: |
206 num_frames = self.CountTracesWithName(FrameTraceName) | 210 num_frames = self.CountTracesWithName(FrameTraceName) |
207 mean_frame_time = Rate(self.all_action_time, num_frames) | 211 mean_frame_time = Rate(self.all_action_time, num_frames) |
208 results.AddValue(scalar.ScalarValue( | 212 results.AddValue(scalar.ScalarValue( |
209 results.current_page, ThreadMeanFrameTimeResultName(self.name), | 213 results.current_page, ThreadMeanFrameTimeResultName(self.name), |
210 'ms', mean_frame_time)) | 214 'ms', mean_frame_time, higher_is_better=False)) |
211 | 215 |
212 def AddDetailedResults(self, num_frames, results): | 216 def AddDetailedResults(self, num_frames, results): |
213 slices_by_category = collections.defaultdict(list) | 217 slices_by_category = collections.defaultdict(list) |
214 for s in self.all_slices: | 218 for s in self.all_slices: |
215 slices_by_category[s.category].append(s) | 219 slices_by_category[s.category].append(s) |
216 all_self_times = [] | 220 all_self_times = [] |
217 for category, slices_in_category in slices_by_category.iteritems(): | 221 for category, slices_in_category in slices_by_category.iteritems(): |
218 self_time = sum([x.self_time for x in slices_in_category]) | 222 self_time = sum([x.self_time for x in slices_in_category]) |
219 all_self_times.append(self_time) | 223 all_self_times.append(self_time) |
220 self_time_result = (float(self_time) / num_frames) if num_frames else 0 | 224 self_time_result = (float(self_time) / num_frames) if num_frames else 0 |
221 results.AddValue(scalar.ScalarValue( | 225 results.AddValue(scalar.ScalarValue( |
222 results.current_page, ThreadDetailResultName(self.name, category), | 226 results.current_page, ThreadDetailResultName(self.name, category), |
223 'ms', self_time_result)) | 227 'ms', self_time_result, higher_is_better=False)) |
224 all_measured_time = sum(all_self_times) | 228 all_measured_time = sum(all_self_times) |
225 idle_time = max(0, self.all_action_time - all_measured_time) | 229 idle_time = max(0, self.all_action_time - all_measured_time) |
226 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 | 230 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 |
227 results.AddValue(scalar.ScalarValue( | 231 results.AddValue(scalar.ScalarValue( |
228 results.current_page, ThreadDetailResultName(self.name, "idle"), | 232 results.current_page, ThreadDetailResultName(self.name, "idle"), |
229 'ms', idle_time_result)) | 233 'ms', idle_time_result, higher_is_better=False)) |
230 | 234 |
231 def CountTracesWithName(self, substring): | 235 def CountTracesWithName(self, substring): |
232 count = 0 | 236 count = 0 |
233 for event in self.all_slices: | 237 for event in self.all_slices: |
234 if substring in event.name: | 238 if substring in event.name: |
235 count += 1 | 239 count += 1 |
236 return count | 240 return count |
237 | 241 |
238 class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric): | 242 class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric): |
239 def __init__(self): | 243 def __init__(self): |
(...skipping 28 matching lines...) Expand all Loading... |
268 num_frames = frame_rate_thread.CountTracesWithName(FrameTraceName) | 272 num_frames = frame_rate_thread.CountTracesWithName(FrameTraceName) |
269 | 273 |
270 # Report the desired results and details. | 274 # Report the desired results and details. |
271 for thread_results in thread_category_results.values(): | 275 for thread_results in thread_category_results.values(): |
272 if thread_results.name in self.results_to_report: | 276 if thread_results.name in self.results_to_report: |
273 thread_results.AddResults(num_frames, results) | 277 thread_results.AddResults(num_frames, results) |
274 # TOOD(nduca): When generic results objects are done, this special case | 278 # TOOD(nduca): When generic results objects are done, this special case |
275 # can be replaced with a generic UI feature. | 279 # can be replaced with a generic UI feature. |
276 if thread_results.name in self.details_to_report: | 280 if thread_results.name in self.details_to_report: |
277 thread_results.AddDetailedResults(num_frames, results) | 281 thread_results.AddDetailedResults(num_frames, results) |
OLD | NEW |