27 import matplotlib.pyplot
as plt
28 from itertools
import zip_longest
as zipl
31 CONV={
"us": 1000,
"ms": 1000*1000}
36 parser = argparse.ArgumentParser(prog=sys.argv[0],
37 formatter_class=argparse.RawDescriptionHelpFormatter,
38 description=
"""hist.py: creates timings histograms from performance samples.""",
40 1. list of the plugins 43 2. histogram of fom_req plugin 44 # python3 hist.py -f png -o write.png -v -u ms -p fom_req 45 "[[auth, zero-copy-initiate], [zero-copy-initiate, tx_open], 46 [tx_open, stobio-launch], [stobio-launch, network-buffer-release], 49 parser.add_argument(
'--db', type=str, required=
False, default=
"m0play.db")
50 group0 = parser.add_mutually_exclusive_group(required=
True)
51 group0.add_argument(
"-p",
"--plugin", type=str, help=
"plugin name")
52 group0.add_argument(
"-l",
"--list", action=
'store_true', help=
"prints plugin list")
53 parser.add_argument(
"-v",
"--verbose", action=
'count', default=0)
54 parser.add_argument(
"-u",
"--time-unit", choices=[
'ms',
'us'], default=
'us')
55 parser.add_argument(
"-o",
"--out", type=str, default=
"img.svg")
56 parser.add_argument(
"-f",
"--fmt", type=str, default=
"svg")
57 parser.add_argument(
"-r",
"--rows", type=int, default=1)
58 parser.add_argument(
"-s",
"--size", nargs=2, type=int, default=[12,4])
59 parser.add_argument(
"range", nargs=
'?', help=
""" 60 "[[from1, to1, [rend]], ... [from_n, to_n, [rend_n]]]" 63 return parser.parse_args()
65 def query(from_, to_, range_end, plug_name, time_unit):
66 q = PLUG[plug_name](from_, to_)
67 logging.info(f
"plug={plug_name} query={q}")
72 cursor = DB.execute_sql(q)
73 fields = [f[0]/DIV
for f
in cursor.fetchall()]
75 max_f = round(
max(fields), 2)
76 min_f = round(
min(fields), 2)
77 avg_f = round(
sum(fields) / len(fields), 2)
78 ag_stat = f
"total max/avg/min {max_f}/{avg_f}/{min_f}" 80 in_range = [f
for f
in fields
if range_end
is None or f < range_end]
81 plt.hist(in_range, 50)
83 plt.title(f
"{from_} \n {to_}")
87 stat = f
"total/range/%: {fs}/{ir}/{round(ir/fs,2)}" 89 plt.xlabel(f
"time({time_unit}) \n {stat} \n {ag_stat}")
90 plt.ylabel(f
"frequency \n")
95 def hist(db_name, plug, range, fmt="svg", out="img.svg", time_unit="us", rows=1, size=(12,4)):
96 stages = yaml.safe_load(range)
100 plt.figure(figsize=size)
101 nr_stages = len(stages)
102 columns = nr_stages // rows + (1
if nr_stages % rows > 0
else 0)
103 for nr,s
in enumerate(stages, 1):
104 r = dict(zipl([
"from",
"to",
"end"], s, fillvalue=
None))
105 plt.subplot(rows, columns, nr)
107 query(r[
"from"], r[
"to"], r[
"end"], plug, time_unit)
110 plt.savefig(fname=out, format=fmt)
113 for _,_,file
in os.walk(
"."):
115 if f.endswith(
".py")
and f.startswith(
"hist__"):
117 plug = importlib.import_module(os.path.splitext(f)[0])
118 PLUG[plug.attr[
'name']] = plug.query
119 logging.info(f
"Plugin loaded: file={f}, " \
120 f
"plugin={plug.attr['name']}")
122 logging.debug(f
"File {f} is not a plugin")
124 if __name__ ==
"__main__":
127 verbosity = { 0: logging.WARN, 1: logging.INFO, 2: logging.DEBUG }
128 logging.basicConfig(format=
'%(asctime)s - %(levelname)-8s %(message)s',
129 level=verbosity[args.verbose
if args.verbose <
max(verbosity)
130 else max(verbosity)])
133 print(
"Loaded plugins:")
134 for k
in PLUG.keys():
138 hist(args.db, args.plugin, args.range, args.fmt, args.out, args.time_unit, args.rows, args.size)
def query(from_, to_, range_end, plug_name, time_unit)
def hist(db_name, plug, range, fmt="svg", out="img.svg", time_unit="us", rows=1, size=(12, 4))
static M0_UNUSED void print(struct m0_be_list *list)
static long long max(long long a, long long b)
static long long min(long long a, long long b)