summaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-10 08:33:28 +0000
committerernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-10 08:33:28 +0000
commitca2094e6657b126ffc67fa8822ccd4b62d2a1f9e (patch)
tree7045819ea006559c3141a1be00aa5b8af0544b28 /tools/perf
parentcd1ef6a6fc7933b86d118a2d425c2df1c6ed6052 (diff)
downloadchromium_src-ca2094e6657b126ffc67fa8822ccd4b62d2a1f9e.zip
chromium_src-ca2094e6657b126ffc67fa8822ccd4b62d2a1f9e.tar.gz
chromium_src-ca2094e6657b126ffc67fa8822ccd4b62d2a1f9e.tar.bz2
telemetry: separated stats collection from metrics calculation.
- Split calculation of smoothness metrics into two parts: A) collection of stats (now from RenderingStats, in the future from traces), B) calculation of the actual benchmark metrics from the stats. - This allows modifying and testing both parts independently R=nduca@chromium.org BUG=264308 Review URL: https://chromiumcodereview.appspot.com/22475007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216832 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/measurements/smoothness.py9
-rw-r--r--tools/perf/metrics/gpu_rendering_stats.py47
-rw-r--r--tools/perf/metrics/smoothness.py181
-rw-r--r--tools/perf/metrics/smoothness_unittest.py125
-rwxr-xr-xtools/perf/run_tests3
5 files changed, 218 insertions, 147 deletions
diff --git a/tools/perf/measurements/smoothness.py b/tools/perf/measurements/smoothness.py
index a553e95..4bdbe07 100644
--- a/tools/perf/measurements/smoothness.py
+++ b/tools/perf/measurements/smoothness.py
@@ -3,6 +3,7 @@
# found in the LICENSE file.
from metrics import loading
from metrics import smoothness
+from metrics.gpu_rendering_stats import GpuRenderingStats
from telemetry.page import page_measurement
class DidNotScrollException(page_measurement.MeasurementFailure):
@@ -59,11 +60,9 @@ class Smoothness(page_measurement.PageMeasurement):
loading.LoadingMetric().AddResults(tab, results)
smoothness.CalcFirstPaintTimeResults(results, tab)
- smoothness.CalcScrollResults(rendering_stats_deltas, results)
- smoothness.CalcTextureUploadResults(rendering_stats_deltas, results)
- smoothness.CalcImageDecodingResults(rendering_stats_deltas, results)
- smoothness.CalcAnalysisResults(rendering_stats_deltas, results)
- smoothness.CalcLatencyResults(rendering_stats_deltas, results)
+
+ benchmark_stats = GpuRenderingStats(rendering_stats_deltas)
+ smoothness.CalcResults(benchmark_stats, results)
if self.options.report_all_results:
for k, v in rendering_stats_deltas.iteritems():
diff --git a/tools/perf/metrics/gpu_rendering_stats.py b/tools/perf/metrics/gpu_rendering_stats.py
new file mode 100644
index 0000000..9af9f9e
--- /dev/null
+++ b/tools/perf/metrics/gpu_rendering_stats.py
@@ -0,0 +1,47 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+class GpuRenderingStats(object):
+ def __init__(self, rendering_stats_deltas):
+ rs = rendering_stats_deltas
+
+ # Scroll Stats
+ self.total_time = rs.get('totalTimeInSeconds', 0)
+ self.screen_frame_count = rs.get('numFramesSentToScreen', 0)
+ self.dropped_frame_count = rs.get('droppedFrameCount', 0)
+ self.impl_thread_scroll_count = rs.get('numImplThreadScrolls', 0)
+ self.main_thread_scroll_count = rs.get('numMainThreadScrolls', 0)
+ self.drawn_layers_count = rs.get('numLayersDrawn', 0)
+ self.missing_tile_count = rs.get('numMissingTiles', 0)
+
+ # Texture Upload Stats
+ self.texture_upload_count = rs.get('textureUploadCount', 0)
+ self.texture_upload_time = rs.get('totalTextureUploadTimeInSeconds', 0)
+ self.commit_count = rs.get('totalCommitCount', 0)
+ self.commit_time = rs.get('totalCommitTimeInSeconds', 0)
+
+ # Image Decoding Stats
+ self.deferred_image_decode_count = rs.get(
+ 'totalDeferredImageDecodeCount', 0)
+ self.deferred_image_decode_time = rs.get(
+ 'totalDeferredImageDecodeTimeInSeconds', 0)
+ self.deferred_image_cache_hits = rs.get(
+ 'totalDeferredImageCacheHitCount', 0)
+ self.image_gathering_count = rs.get('totalImageGatheringCount', 0)
+ self.image_gathering_time = rs.get('totalImageGatheringTimeInSeconds', 0)
+
+ # Tile Analysis Stats
+ self.tile_analysis_count = rs.get('totalTilesAnalyzed', 0)
+ self.tile_analysis_time = rs.get('totalTileAnalysisTimeInSeconds', 0)
+ self.solid_color_tile_analysis_count = rs.get('solidColorTilesAnalyzed', 0)
+
+ # Latency Stats
+ self.input_event_count = rs.get('inputEventCount', 0)
+ self.input_event_latency = rs.get('totalInputLatency', 0)
+ self.touch_ui_count = rs.get('touchUICount', 0)
+ self.touch_ui_latency = rs.get('totalTouchUILatency', 0)
+ self.touch_acked_count = rs.get('touchAckedCount', 0)
+ self.touch_acked_latency = rs.get('totalTouchAckedLatency', 0)
+ self.scroll_update_count = rs.get('scrollUpdateCount', 0)
+ self.scroll_update_latency = rs.get('totalScrollUpdateLatency', 0)
diff --git a/tools/perf/metrics/smoothness.py b/tools/perf/metrics/smoothness.py
index f4ebfbc..c4ec7bc 100644
--- a/tools/perf/metrics/smoothness.py
+++ b/tools/perf/metrics/smoothness.py
@@ -51,66 +51,15 @@ class SmoothnessMetrics(object):
return self._tab.EvaluateJavaScript(
'window.__renderingStats.getDeltas()')
-
-def DivideIfPossibleOrZero(numerator, denominator):
+def Average(numerator, denominator, scale = None, precision = None):
if denominator == 0:
return 0
- return numerator / denominator
-
-def CalcScrollResults(rendering_stats_deltas, results):
- num_frames_sent_to_screen = rendering_stats_deltas['numFramesSentToScreen']
-
- mean_frame_time_seconds = (
- rendering_stats_deltas['totalTimeInSeconds'] /
- float(num_frames_sent_to_screen))
-
- dropped_percent = (
- rendering_stats_deltas['droppedFrameCount'] /
- float(num_frames_sent_to_screen))
-
- num_impl_thread_scrolls = rendering_stats_deltas.get(
- 'numImplThreadScrolls', 0)
- num_main_thread_scrolls = rendering_stats_deltas.get(
- 'numMainThreadScrolls', 0)
-
- percent_impl_scrolled = DivideIfPossibleOrZero(
- float(num_impl_thread_scrolls),
- num_impl_thread_scrolls + num_main_thread_scrolls)
-
- num_layers = (
- rendering_stats_deltas.get('numLayersDrawn', 0) /
- float(num_frames_sent_to_screen))
-
- num_missing_tiles = (
- rendering_stats_deltas.get('numMissingTiles', 0) /
- float(num_frames_sent_to_screen))
-
- results.Add('mean_frame_time', 'ms', round(mean_frame_time_seconds * 1000, 3))
- results.Add('dropped_percent', '%', round(dropped_percent * 100, 1),
- data_type='unimportant')
- results.Add('percent_impl_scrolled', '%',
- round(percent_impl_scrolled * 100, 1),
- data_type='unimportant')
- results.Add('average_num_layers_drawn', '', round(num_layers, 1),
- data_type='unimportant')
- results.Add('average_num_missing_tiles', '', round(num_missing_tiles, 1),
- data_type='unimportant')
-
-def CalcTextureUploadResults(rendering_stats_deltas, results):
- if (('totalCommitCount' not in rendering_stats_deltas)
- or rendering_stats_deltas['totalCommitCount'] == 0) :
- averageCommitTimeMs = 0
- else :
- averageCommitTimeMs = (
- 1000 * rendering_stats_deltas['totalCommitTimeInSeconds'] /
- rendering_stats_deltas['totalCommitCount'])
-
- results.Add('texture_upload_count', 'count',
- rendering_stats_deltas.get('textureUploadCount', 0))
- results.Add('total_texture_upload_time', 'seconds',
- rendering_stats_deltas.get('totalTextureUploadTimeInSeconds', 0))
- results.Add('average_commit_time', 'ms', averageCommitTimeMs,
- data_type='unimportant')
+ avg = float(numerator) / float(denominator)
+ if scale:
+ avg *= scale
+ if precision:
+ avg = round(avg, precision)
+ return avg
def CalcFirstPaintTimeResults(results, tab):
if tab.browser.is_content_shell:
@@ -131,72 +80,78 @@ def CalcFirstPaintTimeResults(results, tab):
results.Add('first_paint', 'ms', round(first_paint_secs * 1000, 1))
-def CalcImageDecodingResults(rendering_stats_deltas, results):
- totalDeferredImageDecodeCount = rendering_stats_deltas.get(
- 'totalDeferredImageDecodeCount', 0)
- totalDeferredImageCacheHitCount = rendering_stats_deltas.get(
- 'totalDeferredImageCacheHitCount', 0)
- totalImageGatheringCount = rendering_stats_deltas.get(
- 'totalImageGatheringCount', 0)
- totalDeferredImageDecodeTimeInSeconds = rendering_stats_deltas.get(
- 'totalDeferredImageDecodeTimeInSeconds', 0)
- totalImageGatheringTimeInSeconds = rendering_stats_deltas.get(
- 'totalImageGatheringTimeInSeconds', 0)
-
- averageImageGatheringTime = DivideIfPossibleOrZero(
- (totalImageGatheringTimeInSeconds * 1000), totalImageGatheringCount)
+def CalcResults(benchmark_stats, results):
+ s = benchmark_stats
+ # Scroll Results
+ results.Add('mean_frame_time', 'ms',
+ Average(s.total_time, s.screen_frame_count, 1000, 3))
+ results.Add('dropped_percent', '%',
+ Average(s.dropped_frame_count, s.screen_frame_count,
+ 100, 1),
+ data_type='unimportant')
+ results.Add('percent_impl_scrolled', '%',
+ Average(s.impl_thread_scroll_count,
+ s.impl_thread_scroll_count +
+ s.main_thread_scroll_count,
+ 100, 1),
+ data_type='unimportant')
+ results.Add('average_num_layers_drawn', '',
+ Average(s.drawn_layers_count, s.screen_frame_count, 1, 1),
+ data_type='unimportant')
+ results.Add('average_num_missing_tiles', '',
+ Average(s.missing_tile_count, s.screen_frame_count, 1, 1),
+ data_type='unimportant')
+
+ # Texture Upload Results
+ results.Add('average_commit_time', 'ms',
+ Average(s.commit_time, s.commit_count, 1000, 3),
+ data_type='unimportant')
+ results.Add('texture_upload_count', 'count',
+ s.texture_upload_count)
+ results.Add('total_texture_upload_time', 'seconds',
+ s.texture_upload_time)
+
+ # Image Decoding Results
results.Add('total_deferred_image_decode_count', 'count',
- totalDeferredImageDecodeCount,
+ s.deferred_image_decode_count,
data_type='unimportant')
results.Add('total_image_cache_hit_count', 'count',
- totalDeferredImageCacheHitCount,
+ s.deferred_image_cache_hits,
data_type='unimportant')
- results.Add('average_image_gathering_time', 'ms', averageImageGatheringTime,
+ results.Add('average_image_gathering_time', 'ms',
+ Average(s.image_gathering_time, s.image_gathering_count,
+ 1000, 3),
data_type='unimportant')
results.Add('total_deferred_image_decoding_time', 'seconds',
- totalDeferredImageDecodeTimeInSeconds,
+ s.deferred_image_decode_time,
data_type='unimportant')
-def CalcAnalysisResults(rendering_stats_deltas, results):
- totalTilesAnalyzed = rendering_stats_deltas.get(
- 'totalTilesAnalyzed', 0)
- solidColorTilesAnalyzed = rendering_stats_deltas.get(
- 'solidColorTilesAnalyzed', 0)
- totalTileAnalysisTimeInSeconds = rendering_stats_deltas.get(
- 'totalTileAnalysisTimeInSeconds', 0)
-
- averageAnalysisTimeMS = \
- 1000 * DivideIfPossibleOrZero(totalTileAnalysisTimeInSeconds,
- totalTilesAnalyzed)
-
+ # Tile Analysis Results
results.Add('total_tiles_analyzed', 'count',
- totalTilesAnalyzed,
+ s.tile_analysis_count,
data_type='unimportant')
results.Add('solid_color_tiles_analyzed', 'count',
- solidColorTilesAnalyzed,
+ s.solid_color_tile_analysis_count,
data_type='unimportant')
results.Add('average_tile_analysis_time', 'ms',
- averageAnalysisTimeMS,
- data_type='unimportant')
-
-def CalcLatency(rendering_stats_deltas, count_name, total_latency_name,
- result_name, results):
- eventCount = rendering_stats_deltas.get(count_name, 0)
- totalLatencyInSeconds = rendering_stats_deltas.get(total_latency_name, 0)
- averageLatency = DivideIfPossibleOrZero(
- (totalLatencyInSeconds * 1000), eventCount)
- results.Add(result_name, 'ms', averageLatency, data_type='unimportant')
-
-def CalcLatencyResults(rendering_stats_deltas, results):
- CalcLatency(rendering_stats_deltas, 'inputEventCount', 'totalInputLatency',
- 'average_latency', results)
- CalcLatency(rendering_stats_deltas, 'touchUICount', 'totalTouchUILatency',
- 'average_touch_ui_latency', results)
- CalcLatency(rendering_stats_deltas, 'touchAckedCount',
- 'totalTouchAckedLatency',
- 'average_touch_acked_latency',
- results)
- CalcLatency(rendering_stats_deltas, 'scrollUpdateCount',
- 'totalScrollUpdateLatency',
- 'average_scroll_update_latency', results)
+ Average(s.tile_analysis_time, s.tile_analysis_count,
+ 1000, 3),
+ data_type='unimportant')
+
+ # Latency Results
+ results.Add('average_latency', 'ms',
+ Average(s.input_event_latency, s.input_event_count,
+ 1000, 3),
+ data_type='unimportant')
+ results.Add('average_touch_ui_latency', 'ms',
+ Average(s.touch_ui_latency, s.touch_ui_count, 1000, 3),
+ data_type='unimportant')
+ results.Add('average_touch_acked_latency', 'ms',
+ Average(s.touch_acked_latency, s.touch_acked_count,
+ 1000, 3),
+ data_type='unimportant')
+ results.Add('average_scroll_update_latency', 'ms',
+ Average(s.scroll_update_latency, s.scroll_update_count,
+ 1000, 3),
+ data_type='unimportant')
diff --git a/tools/perf/metrics/smoothness_unittest.py b/tools/perf/metrics/smoothness_unittest.py
index e7b8778..2a42f9d 100644
--- a/tools/perf/metrics/smoothness_unittest.py
+++ b/tools/perf/metrics/smoothness_unittest.py
@@ -4,43 +4,110 @@
import unittest
from metrics import smoothness
+from metrics.gpu_rendering_stats import GpuRenderingStats
from telemetry.page import page
from telemetry.page.page_measurement_results import PageMeasurementResults
class SmoothnessMetricsUnitTest(unittest.TestCase):
+ def testCalcResultsRealRenderStats(self):
+ mock_rendering_stats_deltas = {
+ 'totalTimeInSeconds': 1.0,
+ 'numFramesSentToScreen': 100,
+ 'droppedFrameCount': 20,
+ 'numImplThreadScrolls': 50,
+ 'numMainThreadScrolls': 50,
+ 'numLayersDrawn': 240,
+ 'numMissingTiles': 10,
+ 'textureUploadCount': 120,
+ 'totalTextureUploadTimeInSeconds': 1.2,
+ 'totalCommitCount': 130,
+ 'totalCommitTimeInSeconds': 1.3,
+ 'totalDeferredImageDecodeCount': 140,
+ 'totalDeferredImageDecodeTimeInSeconds': 1.4,
+ 'totalDeferredImageCacheHitCount': 30,
+ 'totalImageGatheringCount': 150,
+ 'totalImageGatheringTimeInSeconds': 1.5,
+ 'totalTilesAnalyzed': 160,
+ 'totalTileAnalysisTimeInSeconds': 1.6,
+ 'solidColorTilesAnalyzed': 40,
+ 'inputEventCount': 170,
+ 'totalInputLatency': 1.7,
+ 'touchUICount': 180,
+ 'totalTouchUILatency': 1.8,
+ 'touchAckedCount': 190,
+ 'totalTouchAckedLatency': 1.9,
+ 'scrollUpdateCount': 200,
+ 'totalScrollUpdateLatency': 2.0}
+ stats = GpuRenderingStats(mock_rendering_stats_deltas)
- def testCalcResultsFromRAFRenderStats(self):
- rendering_stats = {'droppedFrameCount': 5,
- 'totalTimeInSeconds': 1,
- 'numAnimationFrames': 10,
- 'numFramesSentToScreen': 10}
res = PageMeasurementResults()
res.WillMeasurePage(page.Page('http://foo.com/', None))
- smoothness.CalcScrollResults(rendering_stats, res)
+ smoothness.CalcResults(stats, res)
res.DidMeasurePage()
- self.assertEquals(50, res.page_results[0]['dropped_percent'].value)
+
+ # Scroll Results
+ self.assertAlmostEquals(
+ 1.0 / 100.0 * 1000.0,
+ res.page_results[0]['mean_frame_time'].value, 2)
+ self.assertAlmostEquals(
+ 20.0 / 100.0 * 100.0,
+ res.page_results[0]['dropped_percent'].value)
+ self.assertAlmostEquals(
+ 50.0 / (50.0 + 50.0) * 100.0,
+ res.page_results[0]['percent_impl_scrolled'].value)
self.assertAlmostEquals(
- 100,
- res.page_results[0]['mean_frame_time'].value, 2)
+ 240.0 / 100.0,
+ res.page_results[0]['average_num_layers_drawn'].value)
+ self.assertAlmostEquals(
+ 10.0 / 100.0,
+ res.page_results[0]['average_num_missing_tiles'].value)
- def testCalcResultsRealRenderStats(self):
- rendering_stats = {'numFramesSentToScreen': 60,
- 'globalTotalTextureUploadTimeInSeconds': 0,
- 'totalProcessingCommandsTimeInSeconds': 0,
- 'globalTextureUploadCount': 0,
- 'droppedFrameCount': 0,
- 'textureUploadCount': 0,
- 'numAnimationFrames': 10,
- 'totalPaintTimeInSeconds': 0.35374299999999986,
- 'globalTotalProcessingCommandsTimeInSeconds': 0,
- 'totalTextureUploadTimeInSeconds': 0,
- 'totalRasterizeTimeInSeconds': 0,
- 'totalTimeInSeconds': 1.0}
- res = PageMeasurementResults()
- res.WillMeasurePage(page.Page('http://foo.com/', None))
- smoothness.CalcScrollResults(rendering_stats, res)
- res.DidMeasurePage()
- self.assertEquals(0, res.page_results[0]['dropped_percent'].value)
+ # Texture Upload Results
+ self.assertAlmostEquals(
+ 1.3 / 130.0 * 1000.0,
+ res.page_results[0]['average_commit_time'].value)
+ self.assertEquals(
+ 120,
+ res.page_results[0]['texture_upload_count'].value)
+ self.assertEquals(
+ 1.2,
+ res.page_results[0]['total_texture_upload_time'].value)
+
+ # Image Decoding Results
+ self.assertEquals(
+ 140,
+ res.page_results[0]['total_deferred_image_decode_count'].value)
+ self.assertEquals(
+ 30,
+ res.page_results[0]['total_image_cache_hit_count'].value)
+ self.assertAlmostEquals(
+ 1.5 / 150.0 * 1000.0,
+ res.page_results[0]['average_image_gathering_time'].value)
+ self.assertEquals(
+ 1.4,
+ res.page_results[0]['total_deferred_image_decoding_time'].value)
+
+ # Tile Analysis Results
+ self.assertEquals(
+ 160,
+ res.page_results[0]['total_tiles_analyzed'].value)
+ self.assertEquals(
+ 40,
+ res.page_results[0]['solid_color_tiles_analyzed'].value)
+ self.assertAlmostEquals(
+ 1.6 / 160.0 * 1000.0,
+ res.page_results[0]['average_tile_analysis_time'].value)
+
+ # Latency Results
+ self.assertAlmostEquals(
+ 1.7 / 170.0 * 1000.0,
+ res.page_results[0]['average_latency'].value)
+ self.assertAlmostEquals(
+ 1.8 / 180.0 * 1000.0,
+ res.page_results[0]['average_touch_ui_latency'].value)
+ self.assertAlmostEquals(
+ 1.9 / 190.0 * 1000.0,
+ res.page_results[0]['average_touch_acked_latency'].value)
self.assertAlmostEquals(
- 1000 / 60.,
- res.page_results[0]['mean_frame_time'].value, 2)
+ 2.0 / 200.0 * 1000.0,
+ res.page_results[0]['average_scroll_update_latency'].value)
diff --git a/tools/perf/run_tests b/tools/perf/run_tests
index 275e064..36eefbb 100755
--- a/tools/perf/run_tests
+++ b/tools/perf/run_tests
@@ -25,6 +25,9 @@ if __name__ == '__main__':
start_dir = 'perf_tools'
ret += run_tests.Main(sys.argv[1:], start_dir, top_level_dir, runner)
+ start_dir = 'metrics'
+ ret += run_tests.Main(sys.argv[1:], start_dir, top_level_dir, runner)
+
if runner.result:
runner.result.PrintSummary()
sys.exit(min(ret + runner.result.num_errors, 255))