diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2020-02-24 19:01:53 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2020-02-24 19:01:53 +0100 |
| commit | f313808028c60d7149b6295ded8ccd20237776f7 (patch) | |
| tree | 02b5d3539fa59bb72aa6fef9632e8b35b3631767 /scripts/paper_plots.py | |
| parent | 13a815f78d6165b8c836a23275f03dd2b4d71734 (diff) | |
| download | allocbench-f313808028c60d7149b6295ded8ccd20237776f7.tar.gz allocbench-f313808028c60d7149b6295ded8ccd20237776f7.zip | |
add script to generate pgfplots for the paper
Diffstat (limited to 'scripts/paper_plots.py')
| -rwxr-xr-x | scripts/paper_plots.py | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/scripts/paper_plots.py b/scripts/paper_plots.py new file mode 100755 index 0000000..7b3c537 --- /dev/null +++ b/scripts/paper_plots.py @@ -0,0 +1,244 @@ +#!/usr/bin/env python3 + +# Copyright 2018-2019 Florian Fischer <florian.fl.fischer@fau.de> +# +# This file is part of allocbench. +# +# allocbench is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# allocbench is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with allocbench. If not, see <http://www.gnu.org/licenses/>. +"""Create pgfplots used in our paper""" + +import argparse +import importlib +import inspect +import os +import sys + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0, parentdir) + +import src.allocators.paper +import src.facter +import src.globalvars +import src.plots as plt +from src.util import print_status, print_debug, print_error +from src.util import print_license_and_exit + +ALLOCATOR_NAMES = [a.name for a in src.allocators.paper.allocators] +SURVEY_ALLOCATORS = [a.name for a in src.allocators.paper.allocators if not '-' in a.name] +TCMALLOCS = [a.name for a in src.allocators.paper.allocators if a.name.startswith("TCMalloc")] +ALIGNED_ALLOCATORS = [a.name for a in src.allocators.paper.allocators if a.name.endswith("-Aligned")] + +COLORS=True + +def falsesharing_plots(falsesharing): + args = falsesharing.results["args"] + nthreads = args["threads"] + + falsesharing.results["allocators"] = {k: v for k, v in falsesharing.results["allocators"].items() if k in ALLOCATOR_NAMES} + + plt.pgfplot_legend(falsesharing, colors=COLORS, columns=5) + + # calculate relevant datapoints: speedup, l1-cache-misses + for bench in falsesharing.results["args"]["bench"]: + for allocator in falsesharing.results["allocators"]: + + sequential_perm = falsesharing.Perm(bench=bench, threads=1) + for perm in falsesharing.iterate_args_fixed({"bench": bench}, args=args): + speedup = [] + l1chache_misses = [] + for i, measure in enumerate(falsesharing.results[allocator][perm]): + sequential_time = float(falsesharing.results[allocator] + [sequential_perm][i]["time"]) + measure["speedup"] = sequential_time / float( + measure["time"]) + measure["l1chache_misses"] = eval( + "({L1-dcache-load-misses}/{L1-dcache-loads})*100". + format(**measure)) + + # delete and recalculate stats + del falsesharing.results["stats"] + falsesharing.calc_desc_statistics() + + # pgfplots + for bench in args["bench"]: + plt.pgfplot(falsesharing, + falsesharing.iterate_args_fixed({"bench": bench}, args=args), + "int(perm.threads)", + "{speedup}", + xlabel="Threads", + ylabel="Speedup", + title=f"{bench}: Speedup", + postfix=f"{bench}.speedup", + colors=COLORS) + +def blowup_plots(blowup): + args = blowup.results["args"] + blowup.results["allocators"] = {k: v for k, v in blowup.results["allocators"].items() if k in ALLOCATOR_NAMES} + + # hack ideal rss in data set + blowup.results["allocators"]["Ideal-RSS"] = {"color": "xkcd:gold"} + blowup.results["stats"]["Ideal-RSS"] = {} + for perm in blowup.iterate_args(args=args): + blowup.results["stats"]["Ideal-RSS"][perm] = { + "mean": { + "VmHWM": 1024 * 100 + }, + "std": { + "VmHWM": 0 + } + } + + plt.pgfplot(blowup, + blowup.iterate_args(args), + "'blowup'", + "{VmHWM}/1000", + xlabel="", + ylabel="VmHWM in MB", + title="blowup test", + postfix="vmhwm", + axis_attr="\txtick=data,\n\tsymbolic x coords={blowup}", + bar=True, + colors=COLORS) + +def mysqld_plots(mysql): + args = mysql.results["args"] + mysql.results["allocators"] = {k: v for k, v in mysql.results["allocators"].items() if k in SURVEY_ALLOCATORS} + + plt.pgfplot(mysql, + mysql.iterate_args(args), + "int(perm.nthreads)", + "{mysqld_vmhwm}/1000", + xlabel="threads", + ylabel="VmHWM in MB", + title="Memusage sysbench mysql benchmark", + postfix="vmhwm", + axis_attr="\tybar=0, \tbar width=3", + colors=COLORS) + + plt.pgfplot(mysql, + mysql.iterate_args(args), + "int(perm.nthreads)", + "{transactions}", + xlabel="threads", + ylabel="transactions", + title="Transactions sysbench mysql benchmark", + postfix="transactions", + axis_attr="\tybar=0, \tbar width=3", + colors=COLORS) + +def keydb_plots(keydb): + args = keydb.results["args"] + keydb.results["allocators"] = {k: v for k, v in keydb.results["allocators"].items() if k in SURVEY_ALLOCATORS} + + for fixed_arg in args: + loose_arg = [a for a in args if a != fixed_arg][0] + for arg_value in args[fixed_arg]: + plt.pgfplot(keydb, + keydb.iterate_args_fixed({fixed_arg: arg_value}, args), + f"int(perm.{loose_arg})", + "{totals_ops}", + xlabel=f"{loose_arg}", + ylabel="Total Operations", + title=f"KeyDB Operations: {fixed_arg} {arg_value}", + postfix=f"{fixed_arg}.{arg_value}", + bar=True, + colors=COLORS) + + +def summarize(benchmarks=None, exclude_benchmarks=None): + """summarize the benchmarks in the resdir""" + + cwd = os.getcwd() + + for benchmark, func in {"blowup": blowup_plots, "falsesharing": falsesharing_plots, + "mysql": mysqld_plots, "keydb": keydb_plots}.items(): + if benchmarks and not benchmark in benchmarks: + continue + if exclude_benchmarks and benchmark in exclude_benchmarks: + continue + + bench_module = importlib.import_module(f"src.benchmarks.{benchmark}") + + if not hasattr(bench_module, benchmark): + print_error(f"{benchmark} has no member {benchmark}") + print_error(f"Skipping {benchmark}.") + + bench = getattr(bench_module, benchmark) + + try: + bench.load(src.globalvars.resdir) + except FileNotFoundError: + print_warn(f"Skipping {bench.name}. No results found") + continue + + print_status(f"Summarizing {bench.name} ...") + + res_dir = os.path.join(src.globalvars.resdir, bench.name, "paper") + if not os.path.isdir(res_dir): + os.makedirs(res_dir) + os.chdir(res_dir) + func(bench) + os.chdir(cwd) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Summarize allocbench results in allocator sets") + parser.add_argument("results", help="path to results", type=str) + parser.add_argument("--license", + help="print license info and exit", + action='store_true') + parser.add_argument("--version", + help="print version info and exit", + action='version', + version=f"allocbench {src.facter.allocbench_version()}") + parser.add_argument("-v", "--verbose", help="more output", action='count') + parser.add_argument("-b", + "--benchmarks", + help="benchmarks to summarize", + nargs='+') + parser.add_argument("-x", + "--exclude-benchmarks", + help="benchmarks to exclude", + nargs='+') + parser.add_argument("--latex-preamble", + help="latex code to include in the preamble of generated standalones", + type=str) + parser.add_argument("--no-colors", + help="don't use matplotlib colors for pgfplots", + action="store_true") + + args = parser.parse_args() + + if args.verbose: + src.globalvars.verbosity = args.verbose + + if args.latex_preamble: + src.globalvars.latex_custom_preamble = args.latex_preamble + + if not os.path.isdir(args.results): + print_error(f"{args.results} is no directory") + sys.exit(1) + + if args.no_colors: + COLORS=False + + src.globalvars.resdir = args.results + + # Load facts + src.facter.load_facts(src.globalvars.resdir) + + summarize(benchmarks=args.benchmarks, + exclude_benchmarks=args.exclude_benchmarks) |
