diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-27 17:34:00 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-27 17:34:00 +0200 |
| commit | f0bca4a4103a3dbfc4862cbd76800395b23a74d8 (patch) | |
| tree | 4ec0c28eeb878698736b53bed7e34c7398ddf139 | |
| parent | 7e298c025da08d0de096df3fcac7c8fafac9f5c2 (diff) | |
| download | allocbench-f0bca4a4103a3dbfc4862cbd76800395b23a74d8.tar.gz allocbench-f0bca4a4103a3dbfc4862cbd76800395b23a74d8.zip | |
improve chattymalloc code with pylint
| -rwxr-xr-x | src/chattyparser.py | 100 |
1 files changed, 54 insertions, 46 deletions
diff --git a/src/chattyparser.py b/src/chattyparser.py index e63ec70..d445528 100755 --- a/src/chattyparser.py +++ b/src/chattyparser.py @@ -1,28 +1,31 @@ #!/usr/bin/env python3 +"""Parser and Plotter for the traces produced by chattymalloc""" + import re +import sys + import matplotlib.pyplot as plt import numpy as np -import sys -ptr = "(?:0x)?(?P<ptr>(?:\w+)|(?:\(nil\)))" -size = "(?P<size>\d+)" -alignment = "(?P<alignment>\d+)" +PTR = "(?:0x)?(?P<ptr>(?:\\w+)|(?:\\(nil\\)))" +SIZE = "(?P<size>\\d+)" +ALIGNMENT = "(?P<alignment>\\d+)" -malloc_re = re.compile(f"^m {size} {ptr}$") -free_re = re.compile(f"^f {ptr}$") -calloc_re = re.compile(f"^c (?P<nmemb>\d+) {size} {ptr}$") -realloc_re = re.compile(f"^r {ptr} {size} {ptr.replace('ptr', 'nptr')}$") -memalign_re = re.compile(f"^ma {alignment} {size} {ptr}$") -posix_memalign_re = re.compile(f"^p_ma {ptr} {alignment} {size} (?P<ret>\d+)$") -valloc_re = re.compile(f"^v {size} {ptr}$") -pvalloc_re = re.compile(f"^pv {size} {ptr}$") -aligned_alloc_re = re.compile(f"^a_m {alignment} {size} {ptr}$") +MALLOC_RE = re.compile(f"^m {SIZE} {PTR}$") +FREE_RE = re.compile(f"^f {PTR}$") +CALLOC_RE = re.compile(f"^c (?P<nmemb>\\d+) {SIZE} {PTR}$") +REALLOC_RE = re.compile(f"^r {PTR} {SIZE} {PTR.replace('ptr', 'nptr')}$") +MEMALIGN_RE = re.compile(f"^ma {ALIGNMENT} {SIZE} {PTR}$") +POSIX_MEMALIGN_RE = re.compile(f"^p_ma {PTR} {ALIGNMENT} {SIZE} (?P<ret>\\d+)$") +VALLOC_RE = re.compile(f"^v {SIZE} {PTR}$") +PVALLOC_RE = re.compile(f"^pv {SIZE} {PTR}$") +ALIGNED_ALLOC_RE = re.compile(f"^a_m {ALIGNMENT} {SIZE} {PTR}$") -trace_regex = {"malloc": malloc_re, "free": free_re, "calloc": calloc_re, - "realloc": realloc_re, "memalign": memalign_re, - "posix_memalign": posix_memalign_re, "valloc": valloc_re, - "pvalloc": pvalloc_re, "aligned_alloc": aligned_alloc_re} +TRACE_REGEX = {"malloc": MALLOC_RE, "free": FREE_RE, "calloc": CALLOC_RE, + "realloc": REALLOC_RE, "memalign": MEMALIGN_RE, + "posix_memalign": POSIX_MEMALIGN_RE, "valloc": VALLOC_RE, + "pvalloc": PVALLOC_RE, "aligned_alloc": ALIGNED_ALLOC_RE} def record_allocation(hist, total_size, allocations, ptr, size, coll_size, @@ -46,13 +49,13 @@ def record_allocation(hist, total_size, allocations, ptr, size, coll_size, # realloc returns new pointer if optr and optr in allocations: size -= allocations[optr] - del(allocations[optr]) + del allocations[optr] allocations[ptr] = size if not nohist: hist[size] = hist.get(size, 0) + 1 - if type(total_size[-1]) != int or type(size) != int: + if not isinstance(total_size[-1], int) or not isinstance(size, int): print("invalid type", type(total_size[-1]), type(size)) return @@ -71,13 +74,17 @@ def record_allocation(hist, total_size, allocations, ptr, size, coll_size, elif req_size: total_size.append(total_size[-1]) - del(allocations[ptr]) + del allocations[ptr] # free of invalid pointer elif coll_size: total_size.append(total_size[-1]) def parse(path="chattymalloc.txt", coll_size=True, req_size=None, nohist=False): + """parse a chattymalloc trace + + :returns: a histogram dict, a dict of occurred function calls, list of total requested memory + """ # count function calls calls = {"malloc": 0, "free": 0, "calloc": 0, "realloc": 0, "memalign": 0, "posix_memalign": 0, "valloc": 0, "pvalloc": 0, "aligned_alloc": 0} @@ -87,19 +94,19 @@ def parse(path="chattymalloc.txt", coll_size=True, req_size=None, nohist=False): requested_size = [0] # Dictionary mapping allocation sizes to the count of their appearance hist = {} - ln = 0 + line_count = 0 def record(ptr, size, optr=None, free=False): """Wrapper around record_allocation using local variables from parse""" record_allocation(hist, requested_size, allocations, ptr, size, coll_size, req_size, nohist, optr, free) - with open(path, "r") as f: - for i, l in enumerate(f.readlines()): - ln += 1 + with open(path, "r") as trace_file: + for line in trace_file.readlines(): + line_count += 1 valid_line = False - for func, func_regex in trace_regex.items(): - res = func_regex.match(l) + for func, func_regex in TRACE_REGEX.items(): + res = func_regex.match(line) if res is not None: calls[func] += 1 res = res.groupdict() @@ -117,7 +124,7 @@ def parse(path="chattymalloc.txt", coll_size=True, req_size=None, nohist=False): break if not valid_line: - print("\ninvalid line at", ln, ":", l) + print("\ninvalid line at", line_count, ":", line) return hist, calls, np.array(requested_size) @@ -125,7 +132,7 @@ def parse(path="chattymalloc.txt", coll_size=True, req_size=None, nohist=False): def plot(path): hist, calls, total_sizes = parse(path=path, req_size=None) - plot_hist_ascii(path+".hist", hist, calls) + plot_hist_ascii(f"{path}.hist", hist, calls) top5 = [t[1] for t in sorted([(n, s) for s, n in hist.items()])[-5:]] del hist @@ -140,9 +147,9 @@ def plot_profile(total_sizes, trace_path, plot_path, sizes): plt.plot(x_vals, total_sizes / 1000, marker='', linestyle='-', label="Total requested") - for s in sizes: - _, _, total_size = parse(path=trace_path, nohist=True, req_size=s) - plt.plot(x_vals, total_size / 1000, label=s) + for size in sizes: + _, _, total_size = parse(path=trace_path, nohist=True, req_size=size) + plt.plot(x_vals, total_size / 1000, label=size) plt.legend(loc="lower center") plt.xlabel("Allocations") @@ -159,33 +166,34 @@ def plot_hist_ascii(path, hist, calls): total = sum(calls.values()) - calls["free"] - with open(path, "w") as f: - print("Total function calls:", total, file=f) - for func in trace_regex: - print(func, calls[func], file=f) + with open(path, "w") as hist_file: + print("Total function calls:", total, file=hist_file) + for func in TRACE_REGEX: + print(func, calls[func], file=hist_file) - print(file=f) + print(file=hist_file) - print("allocations <= 64", sum([n for s, n in hist.items() if s <= 64]), file=f) - print("allocations <= 1024", sum([n for s, n in hist.items() if s <= 1024]), file=f) - print("allocations <= 4096", sum([n for s, n in hist.items() if s <= 4096]), file=f) - print(file=f) + print("allocations <= 64", sum([n for s, n in hist.items() if s <= 64]), file=hist_file) + print("allocations <= 1024", sum([n for s, n in hist.items() if s <= 1024]), file=hist_file) + print("allocations <= 4096", sum([n for s, n in hist.items() if s <= 4096]), file=hist_file) + print(file=hist_file) - print("Histogram of sizes:", file=f) + print("Histogram of sizes:", file=hist_file) 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 + for current_bin in sbins: + perc = bins[current_bin]/total*100 binsize = "{:<" + binmaxlength + "} - {:>" + binmaxlength + "}" - print(binsize.format((b)*16, (b+1)*16-1), end=" ", file=f) + print(binsize.format((current_bin)*16, (current_bin+1)*16-1), end=" ", file=hist_file) amount = "{:<" + amountmaxlength + "} {:.2f}% {}" - print(amount.format(bins[b], perc, '*'*int(perc/2)), file=f) + print(amount.format(bins[current_bin], perc, '*'*int(perc/2)), file=hist_file) if __name__ == "__main__": if len(sys.argv) != 2: - print("chattyparser: parse chattymalloc output and create size histogram and memory profile", file=sys.stderr) + print("chattyparser: parse chattymalloc output and", + "create size histogram and memory profile", file=sys.stderr) print(f"Usage: {sys.argv[0]} chattymalloc-file", file=sys.stderr) exit(1) |
