def draw_top_functions(data, event, top_n, outfile, **kwargs): """Draw top N functions on one oprofile event @param data a dictionary of oprofile data, { thread: oprofile_data, ... } @param event event name @param top_n only draw top N functions @param outfile output file path Optional args: @param title the title of the plot (default: 'Oprofile (EVENT_NAME)') @param xlabel the label on x-axes (default: 'Number of Threads') @param ylabel the label on y-axes (default: 'Samples (%)') @param show_all If set to True, shows all functions occured on any oprofile outputs. Otherwise, it only shows the common functions occured on all oprofile outputs. The default value is False. @param threshold Only output the functions that have values larger than the threshold @param loc set legend location. @param ncol set the number of columns of legend. """ # Preprocess optional args title = kwargs.get('title', 'Oprofile (%s)' % event) xlabel = kwargs.get('xlabel', '# of Cores') ylabel = kwargs.get('ylabel', 'Samples (%)') show_all = kwargs.get('show_all', False) threshold = kwargs.get('threshold', 0) loc = kwargs.get('loc', 'upper left') ncol = kwargs.get('ncol', 2) top_n_data = {} for thd, op_data in data.iteritems(): top_n_data[thd] = get_top_n_funcs_in_oprofile(op_data, event, top_n) curves = trans_top_data_to_curves(top_n_data, show_all=show_all, threshold=threshold) mfsplot.plot(curves, title, xlabel, ylabel, outfile, ncol=ncol, loc=loc)
def plot_lock_result(args): """Plot lockstat results """ def _merge_lock_data(curves_by_name, key, lc): if key not in curves_by_name: curves_by_name[key] = (lc[0], np.array(lc[1]), key) else: curves_by_name[key] = (lc[0], curves_by_name[key][1] + lc[1], key) outdir = output_dir(args.dir) files = glob.glob(args.dir + '/*_lockstat.txt') result = analysis.Result() test = '' for filename in files: fields = parse_filename(os.path.basename(filename)) test = fields[0] # print(fields) if test == 'ncpu': fs = fields[2] workload = fields[3] x_value = int(fields[6]) else: fs = fields[1] workload = fields[2] if test == 'multifs': x_value = int(fields[3]) else: x_value = int(fields[5]) lock_data = perftest.parse_lockstat_data(filename) result[fs, workload, x_value] = lock_data xlabel = '# of cores' ylabel = 'Samples' xticks = None ylim = None if test == 'multifs': xlabel = '# of Disks' xticks = [[1, 2, 3, 4], [1, 2, 3, 4]] xlim = (0, 5) output_prefix = os.path.join(outdir, os.path.basename(args.dir)) for fs in result: for wl in result[fs]: plot_data = {} first_nproc = list(result[fs, wl].keys())[0] first_func = list(result[fs, wl, first_nproc].keys())[0] fields = list(result[fs, wl, first_nproc, first_func].keys()) for nproc in result[fs, wl]: for field in fields: if field not in plot_data: plot_data[field] = {} top_n = 10 top_lock_data = perftest.get_top_n_locks( result[fs, wl, nproc], field, top_n) # print(top_lock_data) plot_data[field][nproc] = top_lock_data for field in plot_data: top_lock_curves = perftest.trans_top_data_to_curves( plot_data[field], top_n=5) # if not top_lock_curves: # continue top_curves_by_name = {} for lc in top_lock_curves: if lc[2].startswith('cpufreq_'): continue if ')' in lc[2]: lc = (lc[0], lc[1], lc[2].split(')')[0]) key = lc[2] if lc[2].startswith('dentry->'): key = key.split('.')[0] elif lc[2].startswith('journal->j_state_lock'): key = 'journal->j_state_lock' elif key.startswith('type->i_mutex_dir_key'): key = 'i_mutex_dir_key' _merge_lock_data(top_curves_by_name, key, lc) top_curves = list(top_curves_by_name.values()) # print(top_curves) if not top_curves: continue outfile = output_prefix + \ '_%s_%s_%s_lockstat.%s' % (fs, wl, field, args.ext) plot.plot(top_curves, 'Lockstat (%s)' % field, xlabel, ylabel, outfile, xticks=xticks, xlim=xlim)
def plot_top_perf_functions(data, event, top_n, outfile, **kwargs): """Plot the event curves for the top functions observed from Linux perf tool. @param data a dictionary of perf data, { thread: perf_data, ...}. The key of this directory is the number of process/thread/cpus to observed the data. The keys of this directory will be used as x axis of the figure. @param event event name @param top_n only draw top N functions. @param outfile the output file path. Optional args: @param title the title of the plot (default: 'Perf (EVENT_NAME)') @param xlabel the label on x-axes (default: '# of Cores') @param ylabel the label on y-axes (default: 'Samples (%)') @param show_all If set to True, shows all functions occured on any oprofile outputs. Otherwise, it only shows the common functions occured on all oprofile outputs. The default value is False. @param threshold Only output the functions that have values larger than the threshold @param loc set legend location. @param ncol set the number of columns of legend. """ # Preprocess optional args title = kwargs.get('title', 'Perf (%s)' % event) xlabel = kwargs.get('xlabel', '# of Cores') ylabel = kwargs.get('ylabel', 'Samples (%)') show_all = kwargs.get('show_all', False) threshold = kwargs.get('threshold', 0) loc = kwargs.get('loc', 'upper left') ncol = kwargs.get('ncol', 2) plot_data = data[event] keys = sorted(plot_data.keys()) func_names = set() for v in plot_data.values(): func_names |= v.keys() curve_features = [] for func in func_names: yvalues = [] for x in keys: try: yvalues.append(plot_data[x][func]) except KeyError: yvalues.append(0) if not show_all and threshold > 0 and max(yvalues) < threshold: continue curve_features.append((max(yvalues), (keys, yvalues, func))) # Find top n curves curves = [] curve_features.sort() curve_features.reverse() num_features = min(len(curve_features), top_n) for curve in curve_features[:num_features]: curves.append(curve[1]) mfsplot.plot(curves, title, xlabel, ylabel, outfile, ncol=ncol, loc=loc, ylim=(0, 0.5))