Esempio n. 1
0
    def _get_trace_metrics(self, trace_path):
        """
        Parse a trace (or used cached results) and extract extra metrics from it

        Returns a DataFrame with columns:

        metric,value,units
        """
        cache_path = os.path.join(os.path.dirname(trace_path), 'lisa_trace_metrics.csv')
        if self.use_cached_trace_metrics and os.path.exists(cache_path):
            return pd.read_csv(cache_path)

        # I wonder if this should go in LISA itself? Probably.

        metrics = []
        events = ['irq_handler_entry', 'cpu_frequency', 'nohz_kick', 'sched_switch',
                  'sched_load_cfs_rq', 'sched_load_avg_task', 'thermal_temperature']
        trace = Trace(self.platform, trace_path, events)

        metrics.append(('cpu_wakeup_count', len(trace.data_frame.cpu_wakeups()), None))

        # Helper to get area under curve of multiple CPU active signals
        def get_cpu_time(trace, cpus):
            df = pd.DataFrame([trace.getCPUActiveSignal(cpu) for cpu in cpus])
            return df.sum(axis=1).sum(axis=0)

        clusters = trace.platform.get('clusters')
        if clusters:
            for cluster in clusters.values():
                name = '-'.join(str(c) for c in cluster)

                df = trace.data_frame.cluster_frequency_residency(cluster)
                if df is None or df.empty:
                    self._log.warning("Can't get cluster freq residency from %s",
                                      trace.data_dir)
                else:
                    df = df.reset_index()
                    avg_freq = (df.frequency * df.time).sum() / df.time.sum()
                    metric = 'avg_freq_cluster_{}'.format(name)
                    metrics.append((metric, avg_freq, 'MHz'))

                df = trace.data_frame.trace_event('cpu_frequency')
                df = df[df.cpu == cluster[0]]
                metrics.append(('freq_transition_count_{}'.format(name), len(df), None))

                active_time = area_under_curve(trace.getClusterActiveSignal(cluster))
                metrics.append(('active_time_cluster_{}'.format(name),
                                active_time, 'seconds'))

                metrics.append(('cpu_time_cluster_{}'.format(name),
                                get_cpu_time(trace, cluster), 'cpu-seconds'))

        metrics.append(('cpu_time_total',
                        get_cpu_time(trace, range(trace.platform['cpus_count'])),
                        'cpu-seconds'))

        event = None
        if trace.hasEvents('sched_load_cfs_rq'):
            event = 'sched_load_cfs_rq'
            row_filter = lambda r: r.path == '/'
            column = 'util'
        elif trace.hasEvents('sched_load_avg_cpu'):
            event = 'sched_load_avg_cpu'
            row_filter = lambda r: True
            column = 'util_avg'
        if event:
            df = trace.data_frame.trace_event(event)
            util_sum = (handle_duplicate_index(df)[row_filter]
                        .pivot(columns='cpu')[column].ffill().sum(axis=1))
            avg_util_sum = area_under_curve(util_sum) / (util_sum.index[-1] - util_sum.index[0])
            metrics.append(('avg_util_sum', avg_util_sum, None))

        if trace.hasEvents('thermal_temperature'):
            df = trace.data_frame.trace_event('thermal_temperature')
            for zone, zone_df in df.groupby('thermal_zone'):
                metrics.append(('tz_{}_start_temp'.format(zone),
                                zone_df.iloc[0]['temp_prev'],
                                'milliCelcius'))

                if len(zone_df == 1): # Avoid division by 0
                    avg_tmp = zone_df['temp'].iloc[0]
                else:
                    avg_tmp = (area_under_curve(zone_df['temp'])
                               / (zone_df.index[-1] - zone_df.index[0]))

                metrics.append(('tz_{}_avg_temp'.format(zone),
                                avg_tmp,
                                'milliCelcius'))

        ret = pd.DataFrame(metrics, columns=['metric', 'value', 'units'])
        ret.to_csv(cache_path, index=False)

        return ret
    def _get_trace_metrics(self, trace_path):
        """
        Parse a trace (or used cached results) and extract extra metrics from it

        Returns a DataFrame with columns:

        metric,value,units
        """
        cache_path = os.path.join(os.path.dirname(trace_path),
                                  'lisa_trace_metrics.csv')
        if self.use_cached_trace_metrics and os.path.exists(cache_path):
            return pd.read_csv(cache_path)

        # I wonder if this should go in LISA itself? Probably.

        metrics = []
        events = [
            'irq_handler_entry', 'cpu_frequency', 'nohz_kick', 'sched_switch',
            'sched_load_cfs_rq', 'sched_load_avg_task', 'thermal_temperature'
        ]
        trace = Trace(self.platform, trace_path, events)

        metrics.append(
            ('cpu_wakeup_count', len(trace.data_frame.cpu_wakeups()), None))

        # Helper to get area under curve of multiple CPU active signals
        def get_cpu_time(trace, cpus):
            df = pd.DataFrame([trace.getCPUActiveSignal(cpu) for cpu in cpus])
            return df.sum(axis=1).sum(axis=0)

        clusters = trace.platform.get('clusters')
        if clusters:
            for cluster in clusters.values():
                name = '-'.join(str(c) for c in cluster)

                df = trace.data_frame.cluster_frequency_residency(cluster)
                if df is None or df.empty:
                    self._log.warning(
                        "Can't get cluster freq residency from %s",
                        trace.data_dir)
                else:
                    df = df.reset_index()
                    avg_freq = (df.frequency * df.time).sum() / df.time.sum()
                    metric = 'avg_freq_cluster_{}'.format(name)
                    metrics.append((metric, avg_freq, 'MHz'))

                df = trace.data_frame.trace_event('cpu_frequency')
                df = df[df.cpu == cluster[0]]
                metrics.append(
                    ('freq_transition_count_{}'.format(name), len(df), None))

                active_time = area_under_curve(
                    trace.getClusterActiveSignal(cluster))
                metrics.append(('active_time_cluster_{}'.format(name),
                                active_time, 'seconds'))

                metrics.append(('cpu_time_cluster_{}'.format(name),
                                get_cpu_time(trace, cluster), 'cpu-seconds'))

        metrics.append(
            ('cpu_time_total',
             get_cpu_time(trace,
                          range(trace.platform['cpus_count'])), 'cpu-seconds'))

        event = None
        if trace.hasEvents('sched_load_cfs_rq'):
            event = 'sched_load_cfs_rq'
            row_filter = lambda r: r.path == '/'
            column = 'util'
        elif trace.hasEvents('sched_load_avg_cpu'):
            event = 'sched_load_avg_cpu'
            row_filter = lambda r: True
            column = 'util_avg'
        if event:
            df = trace.data_frame.trace_event(event)
            util_sum = (handle_duplicate_index(df)[row_filter].pivot(
                columns='cpu')[column].ffill().sum(axis=1))
            avg_util_sum = area_under_curve(util_sum) / (util_sum.index[-1] -
                                                         util_sum.index[0])
            metrics.append(('avg_util_sum', avg_util_sum, None))

        if trace.hasEvents('thermal_temperature'):
            df = trace.data_frame.trace_event('thermal_temperature')
            for zone, zone_df in df.groupby('thermal_zone'):
                metrics.append(('tz_{}_start_temp'.format(zone),
                                zone_df.iloc[0]['temp_prev'], 'milliCelcius'))

                if len(zone_df == 1):  # Avoid division by 0
                    avg_tmp = zone_df['temp'].iloc[0]
                else:
                    avg_tmp = (area_under_curve(zone_df['temp']) /
                               (zone_df.index[-1] - zone_df.index[0]))

                metrics.append(
                    ('tz_{}_avg_temp'.format(zone), avg_tmp, 'milliCelcius'))

        ret = pd.DataFrame(metrics, columns=['metric', 'value', 'units'])
        ret.to_csv(cache_path, index=False)

        return ret
Esempio n. 3
0
    def get_trace_metrics(self, trace_path):
        cache_path = os.path.join(os.path.dirname(trace_path),
                                  'lisa_trace_metrics.csv')
        if self.use_cached_trace_metrics and os.path.exists(cache_path):
            return pd.read_csv(cache_path)

        # I wonder if this should go in LISA itself? Probably.

        metrics = []
        events = [
            'irq_handler_entry', 'cpu_frequency', 'nohz_kick', 'sched_switch',
            'sched_load_cfs_rq', 'sched_load_avg_task'
        ]
        trace = Trace(self.platform, trace_path, events)

        if hasattr(trace.data_frame, 'cpu_wakeups'):  # Not merged in LISA yet
            metrics.append(('cpu_wakeup_count',
                            len(trace.data_frame.cpu_wakeups()), None))

        # Helper to get area under curve of multiple CPU active signals
        def get_cpu_time(trace, cpus):
            df = pd.DataFrame([trace.getCPUActiveSignal(cpu) for cpu in cpus])
            return df.sum(axis=1).sum(axis=0)

        clusters = trace.platform.get('clusters')
        if clusters:
            for cluster in clusters.values():
                name = '-'.join(str(c) for c in cluster)

                df = trace.data_frame.cluster_frequency_residency(cluster)
                if df is None or df.empty:
                    print "Can't get cluster freq residency from {}".format(
                        trace.data_dir)
                else:
                    df = df.reset_index()
                    avg_freq = (df.frequency * df.time).sum() / df.time.sum()
                    metric = 'avg_freq_cluster_{}'.format(name)
                    metrics.append((metric, avg_freq, 'MHz'))

                df = trace.data_frame.trace_event('cpu_frequency')
                df = df[df.cpu == cluster[0]]
                metrics.append(
                    ('freq_transition_count_{}'.format(name), len(df), None))

                active_time = area_under_curve(
                    trace.getClusterActiveSignal(cluster))
                metrics.append(('active_time_cluster_{}'.format(name),
                                active_time, 'seconds'))

                metrics.append(('cpu_time_cluster_{}'.format(name),
                                get_cpu_time(trace, cluster), 'cpu-seconds'))

        metrics.append(
            ('cpu_time_total',
             get_cpu_time(trace,
                          range(trace.platform['cpus_count'])), 'cpu-seconds'))

        event = None
        if trace.hasEvents('sched_load_cfs_rq'):
            event = 'sched_load_cfs_rq'
            row_filter = lambda r: r.path == '/'
            column = 'util'
        elif trace.hasEvents('sched_load_avg_cpu'):
            event = 'sched_load_avg_cpu'
            row_filter = lambda r: True
            column = 'util_avg'
        if event:
            df = trace.data_frame.trace_event(event)
            util_sum = (handle_duplicate_index(df)[row_filter].pivot(
                columns='cpu')[column].ffill().sum(axis=1))
            avg_util_sum = area_under_curve(util_sum) / (util_sum.index[-1] -
                                                         util_sum.index[0])
            metrics.append(('avg_util_sum', avg_util_sum, None))

        if trace.hasEvents('nohz_kick'):
            metrics.append(
                ('nohz_kick_count',
                 len(trace.data_frame.trace_event('nohz_kick')), None))

        ret = pd.DataFrame(metrics, columns=['metric', 'value', 'units'])
        if self.use_cached_trace_metrics:
            ret.to_csv(cache_path)

        return ret