def AddImplThreadRenderingStats(mock_timer,
                                thread,
                                first_frame,
                                ref_stats=None):
    """ Adds a random impl thread rendering stats event.

  thread: The timeline model thread to which the event will be added.
  first_frame: Is this the first frame within the bounds of an action?
  ref_stats: A ReferenceRenderingStats object to record expected values.
  """
    # Create randonm data and timestap for impl thread rendering stats.
    data = {
        'frame_count': 1,
        'visible_content_area': random.uniform(0, 100),
        'approximated_visible_content_area': random.uniform(0, 5),
        'checkerboarded_visible_content_area': random.uniform(0, 5)
    }
    timestamp = mock_timer.AdvanceAndGet()

    # Add a slice with the event data to the given thread.
    thread.PushCompleteSlice(
        'benchmark',
        'BenchmarkInstrumentation::ImplThreadRenderingStats',
        timestamp,
        duration=0.0,
        thread_timestamp=None,
        thread_duration=None,
        args={'data': data})

    if not ref_stats:
        return

    # Add timestamp only if a frame was output
    if data['frame_count'] == 1:
        if not first_frame:
            # Add frame_time if this is not the first frame in within the bounds of an
            # action.
            prev_timestamp = ref_stats.frame_timestamps[-1][-1]
            ref_stats.frame_times[-1].append(
                round(timestamp - prev_timestamp, 2))
        ref_stats.frame_timestamps[-1].append(timestamp)

    ref_stats.approximated_pixel_percentages[-1].append(
        round(
            statistics.DivideIfPossibleOrZero(
                data['approximated_visible_content_area'],
                data['visible_content_area']) * 100.0, 3))

    ref_stats.checkerboarded_pixel_percentages[-1].append(
        round(
            statistics.DivideIfPossibleOrZero(
                data['checkerboarded_visible_content_area'],
                data['visible_content_area']) * 100.0, 3))
Пример #2
0
  def _AddV8EventStatsToResults(self, thread, 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')]
    # Find all V8 GC events in the trace.
    for event in thread.IterAllSlices():
      event_stat = _FindV8EventStatForEvent(v8_event_stats, event.name)
      if not event_stat:
        continue

      event_stat.thread_duration += event.thread_duration
      event_stat.max_thread_duration = max(event_stat.max_thread_duration,
                                           event.thread_duration)
      event_stat.count += 1

      parent_idle_task = _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.thread_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

    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)))
      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)))
      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)))
      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)))
      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)))
      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)))
      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)))

    # 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')))
    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')))
    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')))
    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')))
Пример #3
0
 def percentage_thread_duration_during_idle(self):
   return statistics.DivideIfPossibleOrZero(
       100 * self.thread_duration_inside_idle, self.thread_duration)
Пример #4
0
 def Average(self):
     return statistics.DivideIfPossibleOrZero(self.Duration(), self.Count())
Пример #5
0
    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))
      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))