diff options
author | ernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-10 08:33:28 +0000 |
---|---|---|
committer | ernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-10 08:33:28 +0000 |
commit | ca2094e6657b126ffc67fa8822ccd4b62d2a1f9e (patch) | |
tree | 7045819ea006559c3141a1be00aa5b8af0544b28 /tools/perf | |
parent | cd1ef6a6fc7933b86d118a2d425c2df1c6ed6052 (diff) | |
download | chromium_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.py | 9 | ||||
-rw-r--r-- | tools/perf/metrics/gpu_rendering_stats.py | 47 | ||||
-rw-r--r-- | tools/perf/metrics/smoothness.py | 181 | ||||
-rw-r--r-- | tools/perf/metrics/smoothness_unittest.py | 125 | ||||
-rwxr-xr-x | tools/perf/run_tests | 3 |
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)) |