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

Side by Side Diff: tools/perf/metrics/timeline.py

Issue 171013006: Telemetry: Use mimimum tracing for timeline benchmarks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove clock time measurements (cpu is stable and better). Created 6 years, 10 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 # 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 import itertools 5 import itertools
6 6
7 from metrics import Metric 7 from metrics import Metric
8 from telemetry.core.timeline import bounds 8 from telemetry.core.timeline import bounds
9 from telemetry.page import page_measurement 9 from telemetry.page import page_measurement
10 10
11 TRACING_MODE = 'tracing-mode' 11 TRACING_MODE = 'tracing-mode'
12 TIMELINE_MODE = 'timeline-mode' 12 TIMELINE_MODE = 'timeline-mode'
13 13
nduca 2014/02/20 05:35:05 eric how about pulling out the poll_cpu patch from
14 # All tracing categories not disabled-by-default
15 DEFAULT_TRACE_CATEGORIES = None
16
17 # Categories for absolute minimum overhead tracing. This contains no
18 # sub-traces of thread tasks, so it's only useful for capturing the
19 # cpu-time spent on threads (as well as needed benchmark traces)
20 MINIMAL_TRACE_CATEGORIES = ("disabled-by-default-benchmark.poll_cpu,"
21 "benchmark,"
22 "webkit.console,"
23 "trace_event_overhead")
14 24
15 class MissingFramesError(page_measurement.MeasurementFailure): 25 class MissingFramesError(page_measurement.MeasurementFailure):
16 def __init__(self): 26 def __init__(self):
17 super(MissingFramesError, self).__init__( 27 super(MissingFramesError, self).__init__(
18 'No frames found in trace. Unable to normalize results.') 28 'No frames found in trace. Unable to normalize results.')
19 29
20 30
21 class TimelineMetric(Metric): 31 class TimelineMetric(Metric):
22 def __init__(self, mode): 32 def __init__(self, mode):
23 """ Initializes a TimelineMetric object. 33 """ Initializes a TimelineMetric object.
24 """ 34 """
25 super(TimelineMetric, self).__init__() 35 super(TimelineMetric, self).__init__()
26 assert mode in (TRACING_MODE, TIMELINE_MODE) 36 assert mode in (TRACING_MODE, TIMELINE_MODE)
37 self.trace_categories = DEFAULT_TRACE_CATEGORIES
27 self._mode = mode 38 self._mode = mode
28 self._model = None 39 self._model = None
29 self._renderer_process = None 40 self._renderer_process = None
30 self._actions = [] 41 self._actions = []
31 self._action_ranges = [] 42 self._action_ranges = []
32 43
33 def Start(self, page, tab): 44 def Start(self, page, tab):
34 """Starts gathering timeline data. 45 """Starts gathering timeline data.
35 46
36 mode: TRACING_MODE or TIMELINE_MODE 47 mode: TRACING_MODE or TIMELINE_MODE
37 """ 48 """
38 self._model = None 49 self._model = None
39 if self._mode == TRACING_MODE: 50 if self._mode == TRACING_MODE:
40 if not tab.browser.supports_tracing: 51 if not tab.browser.supports_tracing:
41 raise Exception('Not supported') 52 raise Exception('Not supported')
42 tab.browser.StartTracing() 53 tab.browser.StartTracing(self.trace_categories)
43 else: 54 else:
44 assert self._mode == TIMELINE_MODE 55 assert self._mode == TIMELINE_MODE
45 tab.StartTimelineRecording() 56 tab.StartTimelineRecording()
46 57
47 def Stop(self, page, tab): 58 def Stop(self, page, tab):
48 if self._mode == TRACING_MODE: 59 if self._mode == TRACING_MODE:
49 trace_result = tab.browser.StopTracing() 60 trace_result = tab.browser.StopTracing()
50 self._model = trace_result.AsTimelineModel() 61 self._model = trace_result.AsTimelineModel()
51 self._renderer_process = self._model.GetRendererProcessFromTab(tab) 62 self._renderer_process = self._model.GetRendererProcessFromTab(tab)
52 self._action_ranges = [ action.GetActiveRangeOnTimeline(self._model) 63 self._action_ranges = [ action.GetActiveRangeOnTimeline(self._model)
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 thread_category = TimelineThreadCategories[thread_name] 208 thread_category = TimelineThreadCategories[thread_name]
198 return thread_category 209 return thread_category
199 210
200 def ThreadTimeResultName(thread_category): 211 def ThreadTimeResultName(thread_category):
201 return "thread_" + thread_category + "_clock_time_per_frame" 212 return "thread_" + thread_category + "_clock_time_per_frame"
202 213
203 def ThreadCpuTimeResultName(thread_category): 214 def ThreadCpuTimeResultName(thread_category):
204 return "thread_" + thread_category + "_cpu_time_per_frame" 215 return "thread_" + thread_category + "_cpu_time_per_frame"
205 216
206 def ThreadDetailResultName(thread_category, detail): 217 def ThreadDetailResultName(thread_category, detail):
207 return "thread_" + thread_category + "|" + detail 218 detail_sanitized = detail.replace('.','_')
219 return "thread_" + thread_category + "|" + detail_sanitized
208 220
209 221
210 class ResultsForThread(object): 222 class ResultsForThread(object):
211 def __init__(self, model, action_ranges, name): 223 def __init__(self, model, action_ranges, name):
212 self.model = model 224 self.model = model
213 self.toplevel_slices = [] 225 self.toplevel_slices = []
214 self.all_slices = [] 226 self.all_slices = []
215 self.name = name 227 self.name = name
216 self.action_ranges = action_ranges 228 self.action_ranges = action_ranges
217 229
(...skipping 27 matching lines...) Expand all
245 if action_range.Contains(bounds.Bounds.CreateFromEvent(event)): 257 if action_range.Contains(bounds.Bounds.CreateFromEvent(event)):
246 slices_in_actions.append(event) 258 slices_in_actions.append(event)
247 break 259 break
248 return slices_in_actions 260 return slices_in_actions
249 261
250 def AppendThreadSlices(self, thread): 262 def AppendThreadSlices(self, thread):
251 self.all_slices.extend(self.SlicesInActions(thread.all_slices)) 263 self.all_slices.extend(self.SlicesInActions(thread.all_slices))
252 self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices)) 264 self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices))
253 265
254 def AddResults(self, num_frames, results): 266 def AddResults(self, num_frames, results):
255 clock_report_name = ThreadTimeResultName(self.name) 267 cpu_per_frame = (float(self.cpu_time) / num_frames) if num_frames else 0
256 cpu_report_name = ThreadCpuTimeResultName(self.name) 268 results.Add(ThreadCpuTimeResultName(self.name), 'ms', cpu_per_frame)
257 clock_per_frame = (float(self.clock_time) / num_frames) if num_frames else 0
258 cpu_per_frame = (float(self.cpu_time) / num_frames) if num_frames else 0
259 results.Add(clock_report_name, 'ms', clock_per_frame)
260 results.Add(cpu_report_name, 'ms', cpu_per_frame)
261 269
262 def AddDetailedResults(self, num_frames, results): 270 def AddDetailedResults(self, num_frames, results):
263 slices_by_category = collections.defaultdict(list) 271 slices_by_category = collections.defaultdict(list)
264 for s in self.all_slices: 272 for s in self.all_slices:
265 slices_by_category[s.category].append(s) 273 slices_by_category[s.category].append(s)
266 all_self_times = [] 274 all_self_times = []
267 for category, slices_in_category in slices_by_category.iteritems(): 275 for category, slices_in_category in slices_by_category.iteritems():
268 self_time = sum([x.self_time for x in slices_in_category]) 276 self_time = sum([x.self_time for x in slices_in_category])
269 all_self_times.append(self_time) 277 all_self_times.append(self_time)
270 self_time_result = (float(self_time) / num_frames) if num_frames else 0 278 self_time_result = (float(self_time) / num_frames) if num_frames else 0
271 results.Add(ThreadDetailResultName(self.name, category), 279 results.Add(ThreadDetailResultName(self.name, category),
272 'ms', self_time_result) 280 'ms', self_time_result)
273 all_measured_time = sum(all_self_times) 281 all_measured_time = sum(all_self_times)
274 all_action_time = sum([action.bounds for action in self.action_ranges]) 282 all_action_time = sum([action.bounds for action in self.action_ranges])
275 idle_time = max(0, all_action_time - all_measured_time) 283 idle_time = max(0, all_action_time - all_measured_time)
276 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 284 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0
277 results.Add(ThreadDetailResultName(self.name, "idle"), 285 results.Add(ThreadDetailResultName(self.name, "idle"),
278 'ms', idle_time_result) 286 'ms', idle_time_result)
279 287
280 288
281 class ThreadTimesTimelineMetric(TimelineMetric): 289 class ThreadTimesTimelineMetric(TimelineMetric):
282 def __init__(self): 290 def __init__(self):
283 super(ThreadTimesTimelineMetric, self).__init__(TRACING_MODE) 291 super(ThreadTimesTimelineMetric, self).__init__(TRACING_MODE)
284 self.results_to_report = AllThreads 292 # Minimal traces, for minimum noise in CPU-time measurements.
285 self.details_to_report = NoThreads 293 self.trace_categories = MINIMAL_TRACE_CATEGORIES
294 self._results_to_report = AllThreads
295 self._details_to_report = NoThreads
296
297 @property
298 def results_to_report(self):
299 return self._results_to_report
300
301 @results_to_report.setter
302 def results_to_report(self, results_to_report):
303 self._results_to_report = results_to_report
304
305 @property
306 def details_to_report(self):
307 return self._details_to_report
308
309 @details_to_report.setter
310 def details_to_report(self, details_to_report):
311 self._details_to_report = details_to_report
312 # We need the other traces in order to have any details to report.
313 if not details_to_report == NoThreads:
314 self.trace_categories = DEFAULT_TRACE_CATEGORIES
286 315
287 def CountSlices(self, slices, substring): 316 def CountSlices(self, slices, substring):
288 count = 0 317 count = 0
289 for event in slices: 318 for event in slices:
290 if substring in event.name: 319 if substring in event.name:
291 count += 1 320 count += 1
292 return count 321 return count
293 322
294 def AddResults(self, tab, results): 323 def AddResults(self, tab, results):
295 # We need at least one action or we won't count any slices. 324 # We need at least one action or we won't count any slices.
(...skipping 19 matching lines...) Expand all
315 for thread in self._model.GetAllThreads(): 344 for thread in self._model.GetAllThreads():
316 if ThreadCategoryName(thread.name) in FastPathThreads: 345 if ThreadCategoryName(thread.name) in FastPathThreads:
317 thread_category_results['total_fast_path'].AppendThreadSlices(thread) 346 thread_category_results['total_fast_path'].AppendThreadSlices(thread)
318 347
319 # Calculate the number of frames. 348 # Calculate the number of frames.
320 frame_slices = thread_category_results[FrameTraceThreadName].all_slices 349 frame_slices = thread_category_results[FrameTraceThreadName].all_slices
321 num_frames = self.CountSlices(frame_slices, FrameTraceName) 350 num_frames = self.CountSlices(frame_slices, FrameTraceName)
322 351
323 # Report the desired results and details. 352 # Report the desired results and details.
324 for thread_results in thread_category_results.values(): 353 for thread_results in thread_category_results.values():
325 if thread_results.name in self.results_to_report: 354 if thread_results.name in self._results_to_report:
326 thread_results.AddResults(num_frames, results) 355 thread_results.AddResults(num_frames, results)
327 # TOOD(nduca): When generic results objects are done, this special case 356 # TOOD(nduca): When generic results objects are done, this special case
328 # can be replaced with a generic UI feature. 357 # can be replaced with a generic UI feature.
329 if thread_results.name in self.details_to_report: 358 if thread_results.name in self._details_to_report:
330 thread_results.AddDetailedResults(num_frames, results) 359 thread_results.AddDetailedResults(num_frames, results)
OLDNEW
« no previous file with comments | « tools/perf/measurements/thread_times_unittest.py ('k') | tools/perf/metrics/timeline_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698