| Index: tools/perf/metrics/timeline.py
|
| diff --git a/tools/perf/metrics/timeline.py b/tools/perf/metrics/timeline.py
|
| index 211015d14d0fea68394d3a07b7b59bb777eb9d77..f1c4d9ab5bb60ae04e702457333b57ac2b2a6939 100644
|
| --- a/tools/perf/metrics/timeline.py
|
| +++ b/tools/perf/metrics/timeline.py
|
| @@ -2,6 +2,7 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
| import collections
|
| +from telemetry.util.statistics import DivideIfPossibleOrZero
|
|
|
| from telemetry.web_perf.metrics import timeline_based_metric
|
| from telemetry.value import scalar
|
| @@ -100,6 +101,8 @@ OverheadTraceName = "overhead"
|
| FrameTraceName = "::SwapBuffers"
|
| FrameTraceThreadName = "renderer_compositor"
|
|
|
| +def Rate(numerator, denominator):
|
| + return DivideIfPossibleOrZero(numerator, denominator)
|
|
|
| def ClockOverheadForEvent(event):
|
| if (event.category == OverheadTraceCategory and
|
| @@ -124,12 +127,16 @@ def ThreadCategoryName(thread_name):
|
| thread_category = TimelineThreadCategories[thread_name]
|
| return thread_category
|
|
|
| -def ThreadTimeResultName(thread_category):
|
| - return "thread_" + thread_category + "_clock_time_per_frame"
|
| -
|
| def ThreadCpuTimeResultName(thread_category):
|
| + # This isn't a good name, but I don't want to change it and lose continuity.
|
| return "thread_" + thread_category + "_cpu_time_per_frame"
|
|
|
| +def ThreadTasksResultName(thread_category):
|
| + return "tasks_per_frame_" + thread_category
|
| +
|
| +def ThreadMeanFrameTimeResultName(thread_category):
|
| + return "mean_frame_time_" + thread_category
|
| +
|
| def ThreadDetailResultName(thread_category, detail):
|
| detail_sanitized = detail.replace('.','_')
|
| return "thread_" + thread_category + "|" + detail_sanitized
|
| @@ -142,6 +149,8 @@ class ResultsForThread(object):
|
| self.all_slices = []
|
| self.name = name
|
| self.record_ranges = record_ranges
|
| + self.all_action_time = \
|
| + sum([record_range.bounds for record_range in self.record_ranges])
|
|
|
| @property
|
| def clock_time(self):
|
| @@ -179,11 +188,26 @@ class ResultsForThread(object):
|
| self.all_slices.extend(self.SlicesInActions(thread.all_slices))
|
| self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices))
|
|
|
| + # Currently we report cpu-time per frame, tasks per frame, and possibly
|
| + # the mean frame (if there is a trace specified to find it).
|
| def AddResults(self, num_frames, results):
|
| - cpu_per_frame = (float(self.cpu_time) / num_frames) if num_frames else 0
|
| + cpu_per_frame = Rate(self.cpu_time, num_frames)
|
| + tasks_per_frame = Rate(len(self.toplevel_slices), num_frames)
|
| results.AddValue(scalar.ScalarValue(
|
| results.current_page, ThreadCpuTimeResultName(self.name),
|
| 'ms', cpu_per_frame))
|
| + results.AddValue(scalar.ScalarValue(
|
| + results.current_page, ThreadTasksResultName(self.name),
|
| + 'tasks', tasks_per_frame))
|
| + # Report mean frame time if this is the thread we are using for normalizing
|
| + # other results. We could report other frame rates (eg. renderer_main) but
|
| + # this might get confusing.
|
| + if self.name == FrameTraceThreadName:
|
| + num_frames = self.CountTracesWithName(FrameTraceName)
|
| + mean_frame_time = Rate(self.all_action_time, num_frames)
|
| + results.AddValue(scalar.ScalarValue(
|
| + results.current_page, ThreadMeanFrameTimeResultName(self.name),
|
| + 'ms', mean_frame_time))
|
|
|
| def AddDetailedResults(self, num_frames, results):
|
| slices_by_category = collections.defaultdict(list)
|
| @@ -198,14 +222,18 @@ class ResultsForThread(object):
|
| results.current_page, ThreadDetailResultName(self.name, category),
|
| 'ms', self_time_result))
|
| all_measured_time = sum(all_self_times)
|
| - all_action_time = \
|
| - sum([record_range.bounds for record_range in self.record_ranges])
|
| - idle_time = max(0, all_action_time - all_measured_time)
|
| + idle_time = max(0, self.all_action_time - all_measured_time)
|
| idle_time_result = (float(idle_time) / num_frames) if num_frames else 0
|
| results.AddValue(scalar.ScalarValue(
|
| results.current_page, ThreadDetailResultName(self.name, "idle"),
|
| 'ms', idle_time_result))
|
|
|
| + def CountTracesWithName(self, substring):
|
| + count = 0
|
| + for event in self.all_slices:
|
| + if substring in event.name:
|
| + count += 1
|
| + return count
|
|
|
| class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric):
|
| def __init__(self):
|
| @@ -214,13 +242,6 @@ class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric):
|
| self.results_to_report = AllThreads
|
| self.details_to_report = NoThreads
|
|
|
| - def CountSlices(self, slices, substring):
|
| - count = 0
|
| - for event in slices:
|
| - if substring in event.name:
|
| - count += 1
|
| - return count
|
| -
|
| def AddResults(self, model, _, interaction_records, results):
|
| # Set up each thread category for consistant results.
|
| thread_category_results = {}
|
| @@ -243,8 +264,8 @@ class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric):
|
| thread_category_results['total_fast_path'].AppendThreadSlices(thread)
|
|
|
| # Calculate the number of frames.
|
| - frame_slices = thread_category_results[FrameTraceThreadName].all_slices
|
| - num_frames = self.CountSlices(frame_slices, FrameTraceName)
|
| + frame_rate_thread = thread_category_results[FrameTraceThreadName]
|
| + num_frames = frame_rate_thread.CountTracesWithName(FrameTraceName)
|
|
|
| # Report the desired results and details.
|
| for thread_results in thread_category_results.values():
|
|
|