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