def testIsEventInInteractions(self): self.assertFalse( tbm_module.IsEventInInteractions(FakeEvent(0, 100), [ FakeRecord(5, 105), FakeRecord(50, 200), FakeRecord(300, 400) ])) self.assertFalse( tbm_module.IsEventInInteractions( FakeEvent(50, 100), [FakeRecord(105, 205), FakeRecord(0, 45), FakeRecord(0, 90)])) self.assertTrue( tbm_module.IsEventInInteractions( FakeEvent(50, 100), [FakeRecord(5, 105), FakeRecord(0, 45), FakeRecord(0, 90)])) self.assertTrue( tbm_module.IsEventInInteractions( FakeEvent(50, 100), [FakeRecord(5, 45), FakeRecord(0, 45), FakeRecord(0, 100)]))
def _AddJitterResultsInternal(self, events, interactions, results): jitters = [] for event in events: if timeline_based_metric.IsEventInInteractions(event, interactions): jitters.append(event.args['value']) if jitters: results.AddValue(list_of_scalar_values.ListOfScalarValues( page=results.current_page, tir_label=interactions[0].label, name='jitter-amount', units='score', values=jitters, description='Jitter each frame', improvement_direction=improvement_direction.DOWN))
def AddResults(self, model, renderer_thread, interactions, results): v8_events = [] for event in model.IterAllEvents(event_predicate=_IsMessageLoopEvent): if timeline_based_metric.IsEventInInteractions( event, interactions): v8_events.append(event) if v8_events: avg = (sum(e.duration for e in v8_events) / len(v8_events)) results.AddValue( _AverageMessageLoopLatency(value=avg, page=results.current_page, tir_label=interactions[0].label)) else: results.AddValue( _AverageMessageLoopLatency( None, page=results.current_page, tir_label=interactions[0].label, none_value_reason='No v8 events found.'))
def _CollectEvents(self, timeline_model, interactions): for event in timeline_model.IterAllSlices(): if not timeline_based_metric.IsEventInInteractions( event, interactions): continue self._CollectEvent(event)
def AddResults(self, model, renderer_thread, interactions, results): """Adding metrics to the results.""" assert interactions found_events = [] for event in renderer_thread.parent.IterAllEvents( event_predicate=self.IsMediaPlayerMSEvent): if timeline_based_metric.IsEventInInteractions( event, interactions): found_events.append(event) stats_parser = stats_helper.WebMediaPlayerMsRenderingStats( found_events) rendering_stats = stats_parser.GetTimeStats() none_reason = None if not rendering_stats: # Create a TimeStats object whose members have None values. rendering_stats = stats_helper.TimeStats() none_reason = 'No WebMediaPlayerMS::UpdateCurrentFrame event found' elif rendering_stats.invalid_data: # Throw away the data. rendering_stats = stats_helper.TimeStats() none_reason = 'WebMediaPlayerMS data is corrupted.' results.AddValue( list_of_scalar_values.ListOfScalarValues( results.current_page, 'WebRTCRendering_drift_time', 'us', rendering_stats.drift_time, important=True, description='Drift time for a rendered frame', tir_label=interactions[0].label, improvement_direction=improvement_direction.DOWN, none_value_reason=none_reason)) results.AddValue( scalar.ScalarValue( results.current_page, 'WebRTCRendering_percent_badly_out_of_sync', '%', rendering_stats.percent_badly_out_of_sync, important=True, description= 'Percentage of frame which drifted more than 2 VSYNC', tir_label=interactions[0].label, improvement_direction=improvement_direction.DOWN, none_value_reason=none_reason)) results.AddValue( scalar.ScalarValue( results.current_page, 'WebRTCRendering_percent_out_of_sync', '%', rendering_stats.percent_out_of_sync, important=True, description= 'Percentage of frame which drifted more than 1 VSYNC', tir_label=interactions[0].label, improvement_direction=improvement_direction.DOWN, none_value_reason=none_reason)) # I removed the frame distribution list from stats as it is not a metric, # rather it is the underlying data. Also there is no sense of improvement # direction for frame distribution. results.AddValue( scalar.ScalarValue( results.current_page, 'WebRTCRendering_fps', 'fps', rendering_stats.fps, important=True, description='Calculated Frame Rate of video rendering', tir_label=interactions[0].label, improvement_direction=improvement_direction.UP, none_value_reason=none_reason)) results.AddValue( scalar.ScalarValue(results.current_page, 'WebRTCRendering_smoothness_score', '%', rendering_stats.smoothness_score, important=True, description='Smoothness score of rendering', tir_label=interactions[0].label, improvement_direction=improvement_direction.UP, none_value_reason=none_reason)) results.AddValue( scalar.ScalarValue(results.current_page, 'WebRTCRendering_freezing_score', '%', rendering_stats.freezing_score, important=True, description='Freezing score of rendering', tir_label=interactions[0].label, improvement_direction=improvement_direction.UP, none_value_reason=none_reason)) results.AddValue( scalar.ScalarValue( results.current_page, 'WebRTCRendering_rendering_length_error', '%', rendering_stats.rendering_length_error, important=True, description='Rendering length error rate', tir_label=interactions[0].label, improvement_direction=improvement_direction.DOWN, none_value_reason=none_reason))
def _AddV8EventStatsToResults(self, model, interactions, results): v8_event_stats = [ V8EventStat('V8.GCIncrementalMarking', 'v8_gc_incremental_marking', 'incremental marking steps'), V8EventStat('V8.GCScavenger', 'v8_gc_scavenger', 'scavenges'), V8EventStat('V8.GCCompactor', 'v8_gc_mark_compactor', 'mark-sweep-compactor'), V8EventStat('V8.GCFinalizeMC', 'v8_gc_finalize_incremental', 'finalization of incremental marking'), V8EventStat( 'V8.GCFinalizeMCReduceMemory', 'v8_gc_finalize_incremental_reduce_memory', 'finalization of incremental marking with memory reducer') ] label = interactions[0].label name_to_v8_stat = {x.src_event_name: x for x in v8_event_stats} thread_time_not_available = False for event in model.IterAllSlices(): if (not timeline_based_metric.IsEventInInteractions( event, interactions) or not event.name in name_to_v8_stat): continue event_stat = name_to_v8_stat[event.name] if event.thread_duration is None: thread_time_not_available = True event_duration = event.duration else: event_duration = event.thread_duration event_stat.thread_duration += event_duration event_stat.max_thread_duration = max( event_stat.max_thread_duration, event_duration) event_stat.count += 1 parent_idle_task = self._ParentIdleTask(event) if parent_idle_task: allotted_idle_time = parent_idle_task.args['allotted_time_ms'] idle_task_wall_overrun = 0 if event.duration > allotted_idle_time: idle_task_wall_overrun = event.duration - allotted_idle_time # Don't count time over the deadline as being inside idle time. # Since the deadline should be relative to wall clock we compare # allotted_time_ms with wall duration instead of thread duration, and # then assume the thread duration was inside idle for the same # percentage of time. inside_idle = event_duration * statistics.DivideIfPossibleOrZero( event.duration - idle_task_wall_overrun, event.duration) event_stat.thread_duration_inside_idle += inside_idle event_stat.idle_task_overrun_duration += idle_task_wall_overrun if thread_time_not_available: logging.warning( 'thread time is not available in trace data, switch to walltime' ) for v8_event_stat in v8_event_stats: results.AddValue( scalar.ScalarValue( results.current_page, v8_event_stat.result_name, 'ms', v8_event_stat.thread_duration, description=('Total thread duration spent in %s' % v8_event_stat.result_description), tir_label=label, improvement_direction=improvement_direction.DOWN)) results.AddValue( scalar.ScalarValue( results.current_page, '%s_max' % v8_event_stat.result_name, 'ms', v8_event_stat.max_thread_duration, description=('Max thread duration spent in %s' % v8_event_stat.result_description), tir_label=label)) results.AddValue( scalar.ScalarValue( results.current_page, '%s_count' % v8_event_stat.result_name, 'count', v8_event_stat.count, description=('Number of %s' % v8_event_stat.result_description), tir_label=label, improvement_direction=improvement_direction.DOWN)) average_thread_duration = statistics.DivideIfPossibleOrZero( v8_event_stat.thread_duration, v8_event_stat.count) results.AddValue( scalar.ScalarValue( results.current_page, '%s_average' % v8_event_stat.result_name, 'ms', average_thread_duration, description=('Average thread duration spent in %s' % v8_event_stat.result_description), tir_label=label, improvement_direction=improvement_direction.DOWN)) results.AddValue( scalar.ScalarValue( results.current_page, '%s_outside_idle' % v8_event_stat.result_name, 'ms', v8_event_stat.thread_duration_outside_idle, description= ('Total thread duration spent in %s outside of idle tasks' % v8_event_stat.result_description), tir_label=label)) results.AddValue( scalar.ScalarValue( results.current_page, '%s_idle_deadline_overrun' % v8_event_stat.result_name, 'ms', v8_event_stat.idle_task_overrun_duration, description=( 'Total idle task deadline overrun for %s idle tasks' % v8_event_stat.result_description), tir_label=label, improvement_direction=improvement_direction.DOWN)) results.AddValue( scalar.ScalarValue( results.current_page, '%s_percentage_idle' % v8_event_stat.result_name, 'idle%', v8_event_stat.percentage_thread_duration_during_idle, description=('Percentage of %s spent in idle time' % v8_event_stat.result_description), tir_label=label, improvement_direction=improvement_direction.UP)) # Add total metrics. gc_total = sum(x.thread_duration for x in v8_event_stats) gc_total_outside_idle = sum(x.thread_duration_outside_idle for x in v8_event_stats) gc_total_idle_deadline_overrun = sum(x.idle_task_overrun_duration for x in v8_event_stats) gc_total_percentage_idle = statistics.DivideIfPossibleOrZero( 100 * (gc_total - gc_total_outside_idle), gc_total) results.AddValue( scalar.ScalarValue( results.current_page, 'v8_gc_total', 'ms', gc_total, description= 'Total thread duration of all garbage collection events', tir_label=label, improvement_direction=improvement_direction.DOWN)) results.AddValue( scalar.ScalarValue( results.current_page, 'v8_gc_total_outside_idle', 'ms', gc_total_outside_idle, description= ('Total thread duration of all garbage collection events outside of ' 'idle tasks'), tir_label=label, improvement_direction=improvement_direction.DOWN)) results.AddValue( scalar.ScalarValue( results.current_page, 'v8_gc_total_idle_deadline_overrun', 'ms', gc_total_idle_deadline_overrun, description= ('Total idle task deadline overrun for all idle tasks garbage ' 'collection events'), tir_label=label, improvement_direction=improvement_direction.DOWN)) results.AddValue( scalar.ScalarValue( results.current_page, 'v8_gc_total_percentage_idle', 'idle%', gc_total_percentage_idle, description= ('Percentage of the thread duration of all garbage collection ' 'events spent inside of idle tasks'), tir_label=label, improvement_direction=improvement_direction.UP))
'v8_gc_scavenger', 'scavenges'), V8EventStat('V8.GCCompactor', 'v8_gc_mark_compactor', 'mark-sweep-compactor'), V8EventStat('V8.GCFinalizeMC', 'v8_gc_finalize_incremental', 'finalization of incremental marking'), V8EventStat('V8.GCFinalizeMCReduceMemory', 'v8_gc_finalize_incremental_reduce_memory', 'finalization of incremental marking with memory reducer')] label = interactions[0].label name_to_v8_stat = {x.src_event_name : x for x in v8_event_stats} thread_time_not_available = False for event in domain.model.IterAllSlices(): if (not timeline_based_metric.IsEventInInteractions(event, interactions) or not event.name in name_to_v8_stat): continue event_stat = name_to_v8_stat[event.name] if event.thread_duration is None: thread_time_not_available = True event_duration = event.duration else: event_duration = event.thread_duration event_stat.thread_duration += event_duration event_stat.max_thread_duration = max(event_stat.max_thread_duration, event_duration) event_stat.count += 1 parent_idle_task = self._ParentIdleTask(event) if parent_idle_task: