aboutsummaryrefslogtreecommitdiff
path: root/chattyparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'chattyparser.py')
-rw-r--r--chattyparser.py102
1 files changed, 60 insertions, 42 deletions
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)