Commit 44b726ab authored by Florian Fischer's avatar Florian Fischer
Browse files

improve chattyparser and fix analyse add best tex table

parent a67259dc
......@@ -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)
......@@ -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)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment