aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fl.fischer@fau.de>2018-09-25 19:06:19 +0200
committerFlorian Fischer <florian.fl.fischer@fau.de>2018-09-25 19:06:19 +0200
commit44b726abecf154a5c01727d4041cf1b76584acd6 (patch)
tree3806f2975d15c85e96fad6ef35c2673a5d6e4319
parenta67259dc43bdd73047bc88f139b45854c7dde3ad (diff)
downloadallocbench-44b726abecf154a5c01727d4041cf1b76584acd6.tar.gz
allocbench-44b726abecf154a5c01727d4041cf1b76584acd6.zip
improve chattyparser and fix analyse add best tex table
-rw-r--r--benchmark.py77
-rw-r--r--chattyparser.py102
2 files changed, 128 insertions, 51 deletions
diff --git a/benchmark.py b/benchmark.py
index 365397f..1470c4f 100644
--- a/benchmark.py
+++ b/benchmark.py
@@ -157,18 +157,17 @@ class Benchmark (object):
if nolibmemusage:
try:
- hist, calls, reqsize, top5reqsize = chattyparser.parse()
- top5 = [s[1] for s in sorted([(n, s) for s, n in hist.items()])]
- hist, calls, reqsize, top5reqsize = chattyparser.parse(track_top5=top5)
-
- chattyparser.plot_hist_ascii(hist, calls, file_name + ".hist")
- chattyparser.plot_profile(reqsize, top5reqsize, file_name + ".profile.png")
+ chattyparser.plot()
except MemoryError as memerr:
print("Can't Analyse", actual_cmd, "with chattymalloc because",
"to much memory would be needed.")
continue
+ else:
+ with open(file_name + ".hist", "w") as f:
+ f.write(res.stderr)
- os.environ["LD_PRELOAD"] = old_preload or ""
+ if nolibmemusage:
+ os.environ["LD_PRELOAD"] = old_preload or ""
print()
def run(self, verbose=False, runs=5):
@@ -263,7 +262,7 @@ class Benchmark (object):
for target in targets:
y_vals = []
- for perm in self.iterate_args():
+ for perm in self.iterate_args(args=args):
d = []
for m in self.results[target][perm]:
d.append(eval(yval.format(**m)))
@@ -281,7 +280,7 @@ class Benchmark (object):
plt.clf()
def plot_fixed_arg(self, yval, ylabel="'y-label'", xlabel="loose_arg",
- title="default title", filepostfix="", sumdir="", fixed=[]):
+ title="'default title'", filepostfix="", sumdir="", fixed=[]):
args = self.results["args"]
targets = self.results["targets"]
@@ -308,3 +307,63 @@ class Benchmark (object):
plt.savefig(os.path.join(sumdir, ".".join([self.name, arg,
str(arg_value), filepostfix, "png"])))
plt.clf()
+
+ def write_best_doublearg_tex_table(self, evaluation, sort=">", filepostfix="", sumdir="", std=False):
+ args = self.results["args"]
+ keys = list(args.keys())
+ targets = self.results["targets"]
+
+ header_arg = keys[0] if len(args[keys[0]]) < len(args[keys[1]]) else keys[1]
+ row_arg = [arg for arg in args if arg != header_arg][0]
+
+ headers = args[header_arg]
+ print(header_arg, len(headers))
+ rows = args[row_arg]
+ print(row_arg, len(rows))
+
+ cell_text = []
+ for av in rows:
+ row = []
+ for perm in self.iterate_args_fixed({row_arg: av}, args=args):
+ best = []
+ best_val = None
+ for target in targets:
+ d = []
+ for m in self.results[target][perm]:
+ d.append(eval(evaluation.format(**m)))
+ mean = np.mean(d)
+ if target == "glibc":
+ print(perm)
+ print(np.std(d)/mean, "%")
+ if perm.maxsize==64 and perm.nthreads==2:
+ print(target, mean)
+ if not best_val:
+ best = [target]
+ best_val = mean
+ elif (sort == ">" and mean > best_val) or (sort == "<" and mean < best_val):
+
+ best = [target]
+ best_val = mean
+ elif mean == best_val:
+ best.append(target)
+
+ row.append("{}: {:.3f}".format(best[0], best_val))
+ cell_text.append(row)
+
+
+ fname = os.path.join(sumdir, ".".join([self.name, filepostfix, "tex"]))
+ with open(fname , "w") as f:
+ print("\\begin{tabular}{|", end="", file=f)
+ print(" l |" * len(headers),"}", file=f)
+
+ print(header_arg+"/"+row_arg, end=" & ", file=f)
+ for header in headers[:-1]:
+ print(header, end="& ", file=f)
+ print(headers[-1], "\\\\", file=f)
+
+ for i, row in enumerate(cell_text):
+ print(rows[i], end=" & ", file=f)
+ for e in row[:-1]:
+ print(e, end=" & ",file=f)
+ print(row[-1], "\\\\", file=f)
+ print("\\end{tabular}", file=f)
diff --git a/chattyparser.py b/chattyparser.py
index fc6975a..3406b44 100644
--- a/chattyparser.py
+++ b/chattyparser.py
@@ -11,7 +11,7 @@ calloc_re = re.compile("^c (?P<nmemb>\d+) {} {}$".format(size, ptr))
realloc_re = re.compile("^r {} {} {}$".format(ptr, size, ptr.replace("ptr", "nptr")))
memalign_re = re.compile("^mm (?P<alignment>\d+) {} {}$".format(size, ptr))
-def record_allocation(hist, total_size, top5, top5_sizes, allocations, ptr, size, optr=None, add=True):
+def record_allocation(hist, total_size, allocations, ptr, size, coll_size, req_size, nohist, optr=None, add=True):
size = int(size)
if add:
if optr and optr in allocations:
@@ -19,33 +19,35 @@ def record_allocation(hist, total_size, top5, top5_sizes, allocations, ptr, size
del(allocations[optr])
allocations[ptr] = size
- hist[size] = hist.get(size, 0) + 1
+ if not nohist:
+ hist[size] = hist.get(size, 0) + 1
if type(total_size[-1]) != int or type(size) != int:
print("invalid type", type(total_size[-1]), type(size))
return
- total_size.append(total_size[-1] + size)
- for s in top5:
- if s == size:
- top5_sizes[s].append(top5_sizes[s][-1] + s)
- else:
- top5_sizes[s].append(top5_sizes[s][-1])
+
+ if coll_size:
+ if not req_size or size == req_size:
+ total_size.append(total_size[-1] + size)
+ elif req_size:
+ total_size.append(total_size[-1])
elif ptr != "(nil)" and ptr in allocations:
size = allocations[ptr]
- total_size.append(total_size[-1] - size)
- for s in top5:
- if s == size:
- top5_sizes[s].append(top5_sizes[s][-1] - s)
- else:
- top5_sizes[s].append(top5_sizes[s][-1])
+ if coll_size:
+ if not req_size or size == req_size:
+ total_size.append(total_size[-1] - size)
+ elif req_size:
+ total_size.append(total_size[-1])
+
del(allocations[ptr])
+ elif coll_size:
+ total_size.append(total_size[-1])
-def parse(path="chattymalloc.data", track_top5=[]):
+def parse(path="chattymalloc.data", coll_size=True, req_size=None, nohist=False):
tmalloc, tcalloc, trealloc, tfree, tmemalign= 0, 0, 0, 0, 0
allocations = {}
requested_size = [0]
- requested_size_top5 = {s: [0] for s in track_top5}
hist = {}
ln = 0
@@ -55,16 +57,16 @@ def parse(path="chattymalloc.data", track_top5=[]):
res = malloc_re.match(l)
if res != None:
res = res.groupdict()
- record_allocation(hist, requested_size, track_top5, requested_size_top5,
- allocations, res["ptr"], res["size"])
+ record_allocation(hist, requested_size, allocations, res["ptr"],
+ res["size"], coll_size, req_size, nohist)
tmalloc += 1
continue
res = free_re.match(l)
if res != None:
res = res.groupdict()
- record_allocation(hist, requested_size, track_top5, requested_size_top5,
- allocations, res["ptr"], 0, add=False)
+ record_allocation(hist, requested_size, allocations, res["ptr"],
+ 0, coll_size, req_size, nohist, add=False)
tfree +=1
continue
@@ -72,41 +74,50 @@ def parse(path="chattymalloc.data", track_top5=[]):
if res != None:
res = res.groupdict()
size = int(res["nmemb"]) * int(res["size"])
- record_allocation(hist, requested_size, track_top5, requested_size_top5,
- allocations, res["ptr"], size)
+ record_allocation(hist, requested_size, allocations, res["ptr"],
+ size, coll_size, req_size, nohist)
tcalloc += 1
continue
res = realloc_re.match(l)
if res != None:
res = res.groupdict()
- record_allocation(hist, requested_size, track_top5, requested_size_top5,
- allocations, res["nptr"], res["size"], optr=res["ptr"])
+ record_allocation(hist, requested_size, allocations, res["nptr"],
+ res["size"], coll_size, req_size, nohist, optr=res["ptr"])
trealloc += 1
continue
res = memalign_re.match(l)
if res != None:
res = res.groupdict()
- record_allocation(hist, requested_size, track_top5, requested_size_top5,
- allocations, res["ptr"], res["size"])
+ record_allocation(hist, requested_size, allocations, res["ptr"],
+ res["size"], coll_size, req_size, nohist)
tmemalign += 1
continue
print("\ninvalid line at", ln, ":", l)
calls = {"malloc": tmalloc, "free": tfree, "calloc": tcalloc, "realloc": trealloc, "memalign": tmemalign}
- return hist, calls, requested_size, requested_size_top5
+ return hist, calls, requested_size
+
+def plot(path):
+ hist, calls, _ = parse(req_size=None)
+ plot_hist_ascii(path+".hist", hist, calls)
+ top5 = [t[1] for t in sorted([(n, s) for s, n in hist.items()])[-5:]]
-def hist(path="chattymalloc.data"):
- return parse(path=path)[0]
+ del(hist)
+ del(calls)
+ plot_profile(path+".profile.png", top5)
-def plot_profile(total_size, total_top5, path):
- x_vals = list(range(0, len(total_size)))
+
+def plot_profile(path, top5):
+ _, calls, total_size = parse(nohist=True)
+ x_vals = range(0, sum(calls.values()) + 1)
plt.plot(x_vals, total_size, marker='', linestyle='-', label="Total requested")
- for top5 in total_top5:
- plt.plot(x_vals, total_top5[top5], label=top5)
+ for s in top5:
+ _, calls, total_size = parse(nohist=True, req_size=s)
+ plt.plot(x_vals, total_size, label=s)
plt.legend()
plt.xlabel("Allocations")
@@ -115,16 +126,13 @@ def plot_profile(total_size, total_top5, path):
plt.savefig(path)
plt.clf()
-
-def plot_hist_ascii(hist, calls, path):
+def plot_hist_ascii(path, hist, calls):
bins = {}
- bin = 1
for size in sorted(hist):
- if int(size) > bin * 16:
- bin += 1
+ bin = int(size / 16)
bins[bin] = bins.get(bin, 0) + hist[size]
- total = sum(calls.values())
+ total = sum(calls.values()) - calls["free"]
with open(path, "w") as f:
print("Total function calls:", total, file=f)
print("malloc:", calls["malloc"], file=f)
@@ -132,9 +140,19 @@ def plot_hist_ascii(hist, calls, path):
print("realloc:", calls["realloc"], file=f)
print("free:", calls["free"], file=f)
print("memalign:", calls["memalign"], file=f)
+ print(file=f)
+
+ print("< 1024", sum([n for s,n in hist.items() if s < 1024]), file=f)
+ print("< 4096", sum([n for s,n in hist.items() if s < 4096]), file=f)
+ print(file=f)
print("Histogram of sizes:", file=f)
- for b in sorted(bins):
+ sbins = sorted(bins)
+ binmaxlength = str(len(str(sbins[-1])) + 1)
+ amountmaxlength = str(len(str(sorted(bins.values())[-1])))
+ for b in sbins:
perc = bins[b]/total*100
- hist_line = "{} - {}\t{}\t{:.2}% {}"
- print(hist_line.format((b-1)*16, b*16-1, bins[b], perc, '*'*int(perc/2)), file=f)
+ binsize = "{:<" + binmaxlength + "} - {:>" + binmaxlength + "}"
+ print(binsize.format((b)*16, (b+1)*16-1), end=" ", file=f)
+ amount = "{:<" + amountmaxlength + "} {:.2f}% {}"
+ print(amount.format(bins[b], perc, '*'*int(perc/2)), file=f)