From 675bd9abd3e8228a936d1bcb8030912502b81c44 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Mon, 23 Jul 2018 18:15:50 +0200 Subject: remove conprod from benchmark list add memory footprint to mysql also rename the benchmarks --- bench.py | 11 ++- bench_loop.py | 156 -------------------------------------- bench_mysql.py | 217 ----------------------------------------------------- loop.py | 155 ++++++++++++++++++++++++++++++++++++++ mysql.py | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 394 insertions(+), 377 deletions(-) delete mode 100644 bench_loop.py delete mode 100644 bench_mysql.py create mode 100644 loop.py create mode 100644 mysql.py diff --git a/bench.py b/bench.py index 36ea5ec..c7d70f7 100755 --- a/bench.py +++ b/bench.py @@ -2,24 +2,27 @@ import argparse -from bench_loop import loop -from bench_conprod import conprod -from bench_mysql import mysql +from loop import loop +# from bench_conprod import conprod +from mysql import mysql parser = argparse.ArgumentParser(description="benchmark memory allocators") parser.add_argument("-s", "--save", help="save benchmark results to disk", action='store_true') parser.add_argument("-l", "--load", help="load benchmark results from disk", action='store_true') parser.add_argument("-r", "--runs", help="how often the benchmarks run", default=3, type=int) parser.add_argument("-v", "--verbose", help="more output", action='store_true') +parser.add_argument("-b", "--benchmarks", help="benchmarks to run", nargs='+') -benchmarks = [loop, conprod, mysql] +benchmarks = [loop, mysql] def main(): args = parser.parse_args() print (args) for bench in benchmarks: + if args.benchmarks and not bench.name in args.benchmarks: + continue if args.load: bench.load() diff --git a/bench_loop.py b/bench_loop.py deleted file mode 100644 index 6caedb8..0000000 --- a/bench_loop.py +++ /dev/null @@ -1,156 +0,0 @@ -import csv -import pickle -import matplotlib.pyplot as plt -import multiprocessing -import numpy as np -import os -import subprocess - -from benchmark import Benchmark -from common_targets import common_targets - -cmd = ("perf stat -x\; -e cpu-clock:k,cache-references,cache-misses,cycles," - "instructions,branches,faults,migrations " - "build/bench_loop{} 1.2 {} 1000000 {} 10") - -class Benchmark_Loop( Benchmark ): - def __init__(self): - self.file_name = "bench_loop" - self.name = "Loop Stress Benchmark" - self.descrition = """This benchmark makes n allocations in t concurrent threads. - How allocations are freed can be changed with the benchmark - version""", - self.targets = common_targets - self.maxsize = [2 ** x for x in range(6, 16)] - self.nthreads = range(1, multiprocessing.cpu_count() * 2 + 1) - - self.results = {"args" : {"nthreads" : self.nthreads, "maxsize": self.maxsize}, - "targets" : self.targets} - - def prepare(self, verbose=False): - req = ["build/bench_loop"] - for r in req: - if not os.path.isfile(r): - print(r, "not found") - return False - if not os.access(r, os.X_OK): - print(r, "not found") - return False - if verbose: - print(r, "found and executable.") - return True - - - def run(self, verbose=False, runs=3): - args_permutations = [(x,y) for x in self.nthreads for y in self.maxsize] - n = len(args_permutations) - for run in range(1, runs + 1): - print(str(run) + ". run") - - for i, args in enumerate(args_permutations): - print(i + 1, "of", n, "\r", end='') - - # run cmd for each target - for tname, t in self.targets.items(): - result = {"VSZ": [], "RSS" : []} - - os.environ["LD_PRELOAD"] = t[1] - - target_cmd = cmd.format(t[0], *args).split(" ") - if verbose: - print("\n" + tname, t, "\n", " ".join(target_cmd), "\n") - - p = subprocess.Popen(target_cmd, - env=os.environ, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - universal_newlines=True) - - while p.poll() == None: - ps = subprocess.run(["ps", "-F", "--ppid", str(p.pid)], stdout=subprocess.PIPE) - lines = ps.stdout.splitlines() - if len(lines) == 1: # perf hasn't forked yet - continue - tokens = str(lines[1]).split() - result["VSZ"].append(tokens[4]) - result["RSS"].append(tokens[5]) - - p.wait() - - output = p.stderr.read() - - if p.returncode != 0: - print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") - print(tname, t) - print(output) - print(p.stdout) - return False - - if "ERROR: ld.so" in output: - print("\nPreloading of", t[1], "failed for", tname, ".\n Aborting Benchmark.") - print(output) - return False - - # Handle perf output - csvreader = csv.reader(output.splitlines(), delimiter=';') - for row in csvreader: - result[row[2].replace("\\", "")] = row[0].replace("\\", "") - key = (tname, *args) - if not key in self.results: - self.results[key] = [result] - else: - self.results[key].append(result) - - print() - return True - - def summary(self): - # MAXSIZE fixed - nthreads = self.results["args"]["nthreads"] - maxsize = self.results["args"]["maxsize"] - targets = self.results["targets"] - - y_mapping = {v : i for i, v in enumerate(nthreads)} - for size in maxsize: - for target in targets: - y_vals = [0] * len(nthreads) - for mid, measures in self.results.items(): - if mid[0] == target and mid[2] == size: - d = [] - for m in measures: - # nthreads/time = MOPS/S - d.append(mid[1]/float(m["cpu-clock:ku"])) - y_vals[y_mapping[mid[1]]] = np.mean(d) - plt.plot(nthreads, y_vals, marker='.', linestyle='-', label=target) - - plt.legend() - plt.xlabel("threads") - plt.ylabel("MOPS/s") - plt.title("Loop: " + str(size) + "B") - plt.savefig(self.file_name + "." + str(size) + "B.png") - plt.clf() - - # NTHREADS fixed - y_mapping = {v : i for i, v in enumerate(maxsize)} - x_vals = [i + 1 for i in range(0, len(maxsize))] - for n in nthreads: - for target in targets: - y_vals = [0] * len(maxsize) - for mid, measures in self.results.items(): - if mid[0] == target and mid[1] == n: - d = [] - for m in measures: - # nthreads/time = MOPS/S - d.append(n/float(m["cpu-clock:ku"])) - y_vals[y_mapping[mid[2]]] = np.mean(d) - plt.plot(x_vals, y_vals, marker='.', linestyle='-', label=target) - - plt.legend() - plt.xticks(x_vals, maxsize) - plt.xlabel("size in B") - plt.ylabel("MOPS/s") - plt.title("Loop: " + str(n) + "thread(s)") - plt.savefig(self.file_name + "." + str(n) + "threads.png") - plt.clf() - -loop = Benchmark_Loop() diff --git a/bench_mysql.py b/bench_mysql.py deleted file mode 100644 index 1e5c674..0000000 --- a/bench_mysql.py +++ /dev/null @@ -1,217 +0,0 @@ -import copy -import csv -import matplotlib.pyplot as plt -import multiprocessing -import numpy as np -import os -import pickle -import re -import shutil -import subprocess -from time import sleep - -from benchmark import Benchmark -from common_targets import common_targets - -cwd = os.getcwd() - -prepare_cmd = ("sysbench oltp_read_only --db-driver=mysql --mysql-user=root " - "--mysql-socket="+cwd+"/mysql_test/socket --table-size=1000000 prepare").split() - -cmd = ("sysbench oltp_read_only --threads={} --time=10 " - "--db-driver=mysql --mysql-user=root --mysql-socket={}/mysql_test/socket run") - -server_cmd = ("mysqld -h {0}/mysql_test --socket={0}/mysql_test/socket " - "--secure-file-priv=").format(cwd).split() - - -class Benchmark_MYSQL( Benchmark ): - def __init__(self): - self.file_name = "bench_mysql" - self.name = "MYSQL Stress Benchmark" - self.descrition = """See sysbench documentation.""" - self.targets = copy.copy(common_targets) - del(self.targets["klmalloc"]) - self.nthreads = range(1, multiprocessing.cpu_count() * 2 + 1) - - self.results = {"args": {"nthreads" : self.nthreads}, - "targets" : self.targets} - - def start_and_wait_for_server(self, verbose, log=None): - if not log: - log = os.devnull - - with open(log, "ab") as f: - self.server = subprocess.Popen(server_cmd, env=os.environ, - stdout=f, - stderr=f, - universal_newlines=True) - #TODO make sure server comes up !!!! - sleep(5) - return True - - def prepare(self, verbose=False): - ret = True - # Setup mysqld - if not os.path.exists("mysql_test"): - print("Prepare mysqld directory and database") - os.makedirs("mysql_test") - - # Init database - if b"MariaDB" in subprocess.run(["mysqld", "--version"], - stdout=subprocess.PIPE).stdout: - init_db_cmd = ["mysql_install_db", "--basedir=/usr", - "--datadir={}/mysql_test".format(os.getcwd())] - if verbose: - print("MariaDB detected") - else: - init_db_cmd = ["mysqld", "-h", "{}/mysql_test".format(os.getcwd()), - "--initialize-insecure"] - if verbose: - print("Oracle MySQL detected") - - with open(os.devnull, "w") as devnull: - p = subprocess.run(init_db_cmd, - stdout=devnull, stderr=devnull) - ret = ret and p.returncode == 0 - if not ret: - print(p.stderr) - return ret - - if not self.start_and_wait_for_server(verbose, "mysqld.log"): - print("Starting mysqld failed") - return False - - p = subprocess.run("mysql -u root -S {}/mysql_test/socket".format(cwd).split(" "), - input = b"CREATE DATABASE sbtest;\n") - ret = ret and p.returncode == 0 - if not ret: - print(p.stderr) - self.server.kill() - self.server.wait() - return ret - - print("Prepare test table") - p = subprocess.run(prepare_cmd) - ret = ret == p.returncode == 0 - self.server.kill() - ret = ret and self.server.wait() == -9 - - return ret - - def cleanup(self): - if os.path.exists("mysql_test"): - print("Delete mysqld directory") - shutil.rmtree("mysql_test") - - def run(self, verbose=False, save=False, runs=3): - cwd = os.getcwd() - for run in range(1, runs + 1): - print(str(run) + ". run") - - # run cmd for each target - n = len(self.nthreads) - for tname, t in self.targets.items(): - # No custom build mysqld server supported yet. - os.environ["LD_PRELOAD"] = t[1] # set LD_PRELOAD - - if not self.start_and_wait_for_server(verbose, "mysqld.log"): - print("Can't start server for", tname + ".") - print("Aborting Benchmark.") - return False - - for i, thread in enumerate(self.nthreads): - print(tname + ":", i + 1, "of", n, "\r", end='') - - target_cmd = cmd.format(thread, cwd).split(" ") - p = subprocess.run(target_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, - universal_newlines=True) - - if p.returncode != 0: - print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") - print(tname, t) - print(p.stderr) - print(p.stdout) - self.server.kill() - self.server.wait() - return False - - result = {} - result["transactions"] = re.search("transactions:\s*(\d*)", p.stdout).group(1) - result["queries"] = re.search("queries:\s*(\d*)", p.stdout).group(1) - # Latency - result["min"] = re.search("min:\s*(\d*.\d*)", p.stdout).group(1) - result["avg"] = re.search("avg:\s*(\d*.\d*)", p.stdout).group(1) - result["max"] = re.search("max:\s*(\d*.\d*)", p.stdout).group(1) - - key = (tname, thread) - if not key in self.results: - self.results[key] = [result] - else: - self.results[key].append(result) - - print() - - # Get memory stats from server - if "memusage" not in self.results: - self.results["memusage"] = {} - - ps = subprocess.run(["ps", "-F", str(self.server.pid)], stdout=subprocess.PIPE) - tokens = str(ps.stdout.splitlines()[1]).split() - self.results["memusage"][tname] = {"VSZ" : tokens[4], "RSS" : tokens[5]} - - self.server.kill() - self.server.wait() - - if save: - with open(self.name + ".save", "wb") as f: - pickle.dump(self.results, f) - return True - - def summary(self): - # linear plot - nthreads = self.results["args"]["nthreads"] - targets = self.results["targets"] - y_mapping = {v: i for i, v in enumerate(nthreads)} - - for target in targets: - y_vals = [0] * len(nthreads) - for mid, measures in self.results.items(): - if mid[0] == target: - d = [] - for m in measures: - d.append(int(m["transactions"])) - y_vals[y_mapping[mid[1]]] = np.mean(d) - plt.plot(nthreads, y_vals, label=target, linestyle='-', marker='.') - - plt.legend() - plt.xlabel("threads") - plt.ylabel("transactions") - plt.title("sysbench oltp read only") - plt.savefig(self.file_name + ".l.ro.png") - plt.clf() - - # bar plot - nthreads = list(self.results["args"]["nthreads"]) - targets = self.results["targets"] - y_mapping = {v: i for i, v in enumerate(nthreads)} - - for i, target in enumerate(targets): - y_vals = [0] * len(nthreads) - for mid, measures in self.results.items(): - if mid[0] == target: - d = [] - for m in measures: - d.append(int(m["transactions"])) - y_vals[y_mapping[mid[1]]] = np.mean(d) - plt.bar([x-i/8 for x in range(1, len(nthreads) + 1)], y_vals, width=0.2, label=target, align="center") - - plt.legend() - plt.xlabel("threads") - plt.xticks(range(1, len(nthreads) + 1), nthreads) - plt.ylabel("transactions") - plt.title("sysbench oltp read only") - plt.savefig(self.file_name + ".b.ro.png") - plt.clf() - -mysql = Benchmark_MYSQL() diff --git a/loop.py b/loop.py new file mode 100644 index 0000000..a70bd92 --- /dev/null +++ b/loop.py @@ -0,0 +1,155 @@ +import csv +import pickle +import matplotlib.pyplot as plt +import multiprocessing +import numpy as np +import os +import subprocess + +from benchmark import Benchmark +from common_targets import common_targets + +cmd = ("perf stat -x\; -e cpu-clock:k,cache-references,cache-misses,cycles," + "instructions,branches,faults,migrations " + "build/bench_loop{} 1.2 {} 1000000 {} 10") + +class Benchmark_Loop( Benchmark ): + def __init__(self): + self.name = "loop" + self.descrition = """This benchmark makes n allocations in t concurrent threads. + How allocations are freed can be changed with the benchmark + version""", + self.targets = common_targets + self.maxsize = [2 ** x for x in range(6, 16)] + self.nthreads = range(1, multiprocessing.cpu_count() * 2 + 1) + + self.results = {"args" : {"nthreads" : self.nthreads, "maxsize": self.maxsize}, + "targets" : self.targets} + + def prepare(self, verbose=False): + req = ["build/bench_loop"] + for r in req: + if not os.path.isfile(r): + print(r, "not found") + return False + if not os.access(r, os.X_OK): + print(r, "not found") + return False + if verbose: + print(r, "found and executable.") + return True + + + def run(self, verbose=False, runs=3): + args_permutations = [(x,y) for x in self.nthreads for y in self.maxsize] + n = len(args_permutations) + for run in range(1, runs + 1): + print(str(run) + ". run") + + for i, args in enumerate(args_permutations): + print(i + 1, "of", n, "\r", end='') + + # run cmd for each target + for tname, t in self.targets.items(): + result = {"VSZ": [], "RSS" : []} + + os.environ["LD_PRELOAD"] = t[1] + + target_cmd = cmd.format(t[0], *args).split(" ") + if verbose: + print("\n" + tname, t, "\n", " ".join(target_cmd), "\n") + + p = subprocess.Popen(target_cmd, + env=os.environ, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + universal_newlines=True) + + while p.poll() == None: + ps = subprocess.run(["ps", "-F", "--ppid", str(p.pid)], stdout=subprocess.PIPE) + lines = ps.stdout.splitlines() + if len(lines) == 1: # perf hasn't forked yet + continue + tokens = str(lines[1]).split() + result["VSZ"].append(tokens[4]) + result["RSS"].append(tokens[5]) + + p.wait() + + output = p.stderr.read() + + if p.returncode != 0: + print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") + print(tname, t) + print(output) + print(p.stdout) + return False + + if "ERROR: ld.so" in output: + print("\nPreloading of", t[1], "failed for", tname, ".\n Aborting Benchmark.") + print(output) + return False + + # Handle perf output + csvreader = csv.reader(output.splitlines(), delimiter=';') + for row in csvreader: + result[row[2].replace("\\", "")] = row[0].replace("\\", "") + key = (tname, *args) + if not key in self.results: + self.results[key] = [result] + else: + self.results[key].append(result) + + print() + return True + + def summary(self): + # MAXSIZE fixed + nthreads = self.results["args"]["nthreads"] + maxsize = self.results["args"]["maxsize"] + targets = self.results["targets"] + + y_mapping = {v : i for i, v in enumerate(nthreads)} + for size in maxsize: + for target in targets: + y_vals = [0] * len(nthreads) + for mid, measures in self.results.items(): + if mid[0] == target and mid[2] == size: + d = [] + for m in measures: + # nthreads/time = MOPS/S + d.append(mid[1]/float(m["cpu-clock:ku"])) + y_vals[y_mapping[mid[1]]] = np.mean(d) + plt.plot(nthreads, y_vals, marker='.', linestyle='-', label=target) + + plt.legend() + plt.xlabel("threads") + plt.ylabel("MOPS/s") + plt.title("Loop: " + str(size) + "B") + plt.savefig(self.name + "." + str(size) + "B.png") + plt.clf() + + # NTHREADS fixed + y_mapping = {v : i for i, v in enumerate(maxsize)} + x_vals = [i + 1 for i in range(0, len(maxsize))] + for n in nthreads: + for target in targets: + y_vals = [0] * len(maxsize) + for mid, measures in self.results.items(): + if mid[0] == target and mid[1] == n: + d = [] + for m in measures: + # nthreads/time = MOPS/S + d.append(n/float(m["cpu-clock:ku"])) + y_vals[y_mapping[mid[2]]] = np.mean(d) + plt.plot(x_vals, y_vals, marker='.', linestyle='-', label=target) + + plt.legend() + plt.xticks(x_vals, maxsize) + plt.xlabel("size in B") + plt.ylabel("MOPS/s") + plt.title("Loop: " + str(n) + "thread(s)") + plt.savefig(self.name + "." + str(n) + "threads.png") + plt.clf() + +loop = Benchmark_Loop() diff --git a/mysql.py b/mysql.py new file mode 100644 index 0000000..22c9f0d --- /dev/null +++ b/mysql.py @@ -0,0 +1,232 @@ +import copy +import csv +import matplotlib.pyplot as plt +import multiprocessing +import numpy as np +import os +import pickle +import re +import shutil +import subprocess +from time import sleep + +from benchmark import Benchmark +from common_targets import common_targets + +cwd = os.getcwd() + +prepare_cmd = ("sysbench oltp_read_only --db-driver=mysql --mysql-user=root " + "--mysql-socket="+cwd+"/mysql_test/socket --table-size=1000000 prepare").split() + +cmd = ("sysbench oltp_read_only --threads={} --time=10 " + "--db-driver=mysql --mysql-user=root --mysql-socket={}/mysql_test/socket run") + +server_cmd = ("mysqld -h {0}/mysql_test --socket={0}/mysql_test/socket " + "--secure-file-priv=").format(cwd).split() + + +class Benchmark_MYSQL( Benchmark ): + def __init__(self): + self.name = "mysql" + self.descrition = """See sysbench documentation.""" + self.targets = copy.copy(common_targets) + del(self.targets["klmalloc"]) + self.nthreads = range(1, multiprocessing.cpu_count() * 2 + 1) + + self.results = {"args": {"nthreads" : self.nthreads}, + "targets" : self.targets} + + def start_and_wait_for_server(self, verbose, log=None): + if not log: + log = os.devnull + + with open(log, "ab") as f: + self.server = subprocess.Popen(server_cmd, env=os.environ, + stdout=f, + stderr=f, + universal_newlines=True) + #TODO make sure server comes up !!!! + sleep(5) + return True + + def prepare(self, verbose=False): + ret = True + # Setup mysqld + if not os.path.exists("mysql_test"): + print("Prepare mysqld directory and database") + os.makedirs("mysql_test") + + # Init database + if b"MariaDB" in subprocess.run(["mysqld", "--version"], + stdout=subprocess.PIPE).stdout: + init_db_cmd = ["mysql_install_db", "--basedir=/usr", + "--datadir={}/mysql_test".format(os.getcwd())] + if verbose: + print("MariaDB detected") + else: + init_db_cmd = ["mysqld", "-h", "{}/mysql_test".format(os.getcwd()), + "--initialize-insecure"] + if verbose: + print("Oracle MySQL detected") + + with open(os.devnull, "w") as devnull: + p = subprocess.run(init_db_cmd, + stdout=devnull, stderr=devnull) + ret = ret and p.returncode == 0 + if not ret: + print(p.stderr) + return ret + + if not self.start_and_wait_for_server(verbose, "mysqld.log"): + print("Starting mysqld failed") + return False + + p = subprocess.run("mysql -u root -S {}/mysql_test/socket".format(cwd).split(" "), + input = b"CREATE DATABASE sbtest;\n") + ret = ret and p.returncode == 0 + if not ret: + print(p.stderr) + self.server.kill() + self.server.wait() + return ret + + print("Prepare test table") + p = subprocess.run(prepare_cmd) + ret = ret == p.returncode == 0 + self.server.kill() + ret = ret and self.server.wait() == -9 + + return ret + + def cleanup(self): + if os.path.exists("mysql_test"): + print("Delete mysqld directory") + shutil.rmtree("mysql_test") + + def run(self, verbose=False, save=False, runs=3): + cwd = os.getcwd() + for run in range(1, runs + 1): + print(str(run) + ". run") + + # run cmd for each target + n = len(self.nthreads) + for tname, t in self.targets.items(): + # No custom build mysqld server supported yet. + os.environ["LD_PRELOAD"] = t[1] # set LD_PRELOAD + + if not self.start_and_wait_for_server(verbose, "mysqld.log"): + print("Can't start server for", tname + ".") + print("Aborting Benchmark.") + return False + + # Get initial memory footprint + ps = subprocess.run(["ps", "-F", str(self.server.pid)], stdout=subprocess.PIPE) + tokens = str(ps.stdout.splitlines()[1]).split() + if not tname in self.results["memusage"]: + self.results["memusage"] = [] + self.results["memusage"].append({"VSZ_start" : tokens[4], "RSS_start" : tokens[5]}) + + for i, thread in enumerate(self.nthreads): + print(tname + ":", i + 1, "of", n, "\r", end='') + + target_cmd = cmd.format(thread, cwd).split(" ") + p = subprocess.run(target_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, + universal_newlines=True) + + if p.returncode != 0: + print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") + print(tname, t) + print(p.stderr) + print(p.stdout) + self.server.kill() + self.server.wait() + return False + + result = {} + result["transactions"] = re.search("transactions:\s*(\d*)", p.stdout).group(1) + result["queries"] = re.search("queries:\s*(\d*)", p.stdout).group(1) + # Latency + result["min"] = re.search("min:\s*(\d*.\d*)", p.stdout).group(1) + result["avg"] = re.search("avg:\s*(\d*.\d*)", p.stdout).group(1) + result["max"] = re.search("max:\s*(\d*.\d*)", p.stdout).group(1) + + key = (tname, thread) + if not key in self.results: + self.results[key] = [result] + else: + self.results[key].append(result) + + print() + + # Get final memory footprint + ps = subprocess.run(["ps", "-F", str(self.server.pid)], stdout=subprocess.PIPE) + tokens = str(ps.stdout.splitlines()[1]).split() + self.results["memusage"][tname][run].update({"VSZ_end" : tokens[4], "RSS_end" : tokens[5]}) + + self.server.kill() + self.server.wait() + + if save: + with open(self.name + ".save", "wb") as f: + pickle.dump(self.results, f) + return True + + def summary(self): + # linear plot + nthreads = self.results["args"]["nthreads"] + targets = self.results["targets"] + y_mapping = {v: i for i, v in enumerate(nthreads)} + + for target in targets: + y_vals = [0] * len(nthreads) + for mid, measures in self.results.items(): + if mid[0] == target: + d = [] + for m in measures: + d.append(int(m["transactions"])) + y_vals[y_mapping[mid[1]]] = np.mean(d) + plt.plot(nthreads, y_vals, label=target, linestyle='-', marker='.') + + plt.legend() + plt.xlabel("threads") + plt.ylabel("transactions") + plt.title("sysbench oltp read only") + plt.savefig(self.name + ".l.ro.png") + plt.clf() + + # bar plot + nthreads = list(self.results["args"]["nthreads"]) + targets = self.results["targets"] + y_mapping = {v: i for i, v in enumerate(nthreads)} + + for i, target in enumerate(targets): + y_vals = [0] * len(nthreads) + for mid, measures in self.results.items(): + if mid[0] == target: + d = [] + for m in measures: + d.append(int(m["transactions"])) + y_vals[y_mapping[mid[1]]] = np.mean(d) + plt.bar([x-i/8 for x in range(1, len(nthreads) + 1)], y_vals, width=0.2, label=target, align="center") + + plt.legend() + plt.xlabel("threads") + plt.xticks(range(1, len(nthreads) + 1), nthreads) + plt.ylabel("transactions") + plt.title("sysbench oltp read only") + plt.savefig(self.name + ".b.ro.png") + plt.clf() + + # memusage + for target, measures in self.results["memusage"].items(): + vsz_growth = [] + rss_growth = [] + for m in measures: + vsz_growth.append(m["VSZ_start"] - m["VSZ_end"]) + rss_growth.append(m["RSS_start"] - m["RSS_end"]) + print(target, "memory footprint:") + print("\t avg vsz growth:", np.mean(vsz_growth)) + print("\t avg rss growth:", np.mean(rss_growth)) + + +mysql = Benchmark_MYSQL() -- cgit v1.2.3