Преглед изворни кода

Python script to create plots from traces

Ioannis Koutras пре 12 година
родитељ
комит
7e385bf0e2
1 измењених фајлова са 166 додато и 0 уклоњено
  1. 166 0
      scripts/plot_memory_usage.py

+ 166 - 0
scripts/plot_memory_usage.py

@@ -0,0 +1,166 @@
+#!/usr/bin/python
+
+import os, sys
+import subprocess
+import re
+import math
+
+import matplotlib
+matplotlib.use('Agg')
+import matplotlib.pyplot as plt
+from matplotlib.ticker import FuncFormatter
+import numpy as np
+
+import itertools
+
+import pdb
+
+def add_event(dictionary, scale):
+    if scale in dictionary:
+        dictionary[scale] = dictionary[scale] + 1
+    else:
+        dictionary[scale] = 1
+
+def convert(num):
+    if num >= 1048576:
+        return '{} MB'.format((num / 1048576))
+    elif num >= 1024:
+        return '{} kB'.format((num / 1024))
+    # We start from 1 - 32 bytes anyway
+    elif num == 17:
+        return '1 B'
+    else:
+        return '{} B'.format(num)
+
+def megabytes(x, pos):
+    return '%1.f MB' % (x / 1048576)
+
+def main(arg1):
+
+    print('Checking how many memory events are in the log...'),
+    sys.stdout.flush()
+    command = 'cat {} | grep "^dmmlib - ms all" | wc -l'.format(arg1)
+    num_events = int(subprocess.check_output(command, shell=True))
+    # FIXME exit if there are no events
+    print('{}.'.format(num_events))
+
+    sampling = False
+    points_to_draw = 50000
+    if num_events >= points_to_draw:
+        sampling = True
+        sample_pack = int(math.ceil(float(num_events) / points_to_draw))
+    req_sampling_check = 0
+    alloc_sampling_check = 0
+
+    # Example: dmmlib - m 0x7f5817829178 26
+    malloc_pattern = re.compile(r'^dmmlib - m (0x\w+) (\d+)')
+    # Example: dmmlib - ms req 609
+    requested_pattern = re.compile('^dmmlib - ms req (\d+)')
+    # Example: dmmlib - ms all 1280
+    allocated_pattern = re.compile('^dmmlib - ms all (\d+)')
+
+    scale_dictionary = {}
+    requested = []
+    allocated = []
+
+    print('Parsing the log file...')
+    sys.stdout.flush()
+    with open(arg1) as infile:
+        for line in infile:
+
+            malloc_match = malloc_pattern.match(line)
+            if malloc_match:
+                request_size = int(malloc_match.group(2))
+                scale = int(math.ceil(math.log(request_size, 2)))
+                # Starting bar is up to 32 bytes
+                if scale < 5:
+                    scale = 5
+                add_event(scale_dictionary, scale)
+
+            requested_match = requested_pattern.match(line)
+            if requested_match:
+                if req_sampling_check == 0:
+                        requested.append(int(requested_match.group(1)))
+                        if sampling:
+                            req_sampling_check += 1
+                else:
+                    if req_sampling_check == sample_pack - 1:
+                        req_sampling_check = 0
+                    else:
+                        req_sampling_check += 1
+
+            allocated_match = allocated_pattern.match(line)
+            if allocated_match:
+                if alloc_sampling_check == 0:
+                        allocated.append(int(allocated_match.group(1)))
+                        if sampling:
+                            alloc_sampling_check += 1
+                else:
+                    if alloc_sampling_check == sample_pack - 1:
+                        alloc_sampling_check = 0
+                    else:
+                        alloc_sampling_check += 1
+    print('Done')
+
+    # Histogram of requested sizes - START
+    print('Creating a histogram plot for the requested sizes...'),
+    sys.stdout.flush()
+
+    hist_fig = plt.figure()    
+    hist_ax = hist_fig.add_subplot(111)
+
+    size_data = zip(*scale_dictionary.items())
+    hist_rects = hist_ax.bar(np.array(size_data[0]) - 4, size_data[1], width=0.2, align='center')
+
+    sorted_keys = np.array(sorted(scale_dictionary.keys()))
+    start = np.power(2, sorted_keys - 1) + 1
+    end = np.power(2, sorted_keys)
+
+    xlabels = [ '{} - {}'.format(convert(t[0]), convert(t[1])) for t in itertools.izip(start, end) ]
+
+    hist_ax.set_xticks(sorted_keys - 4)
+    hist_ax.set_xticklabels(xlabels)
+    # Show only the xticks of the bottom X axis
+    hist_ax.get_xaxis().tick_bottom()
+    
+    hist_ax.set_title('Memory request sizes')
+    hist_ax.set_ylabel('Counts')
+
+    hist_fig.autofmt_xdate()
+        
+    hist_fig.savefig('{}_histogram.pdf'.format(arg1))
+
+    print('Done.')
+    # Histogram of requested sizes - END
+
+    # Memory usage - START
+    print('Creating a plot for the memory utilization timeline...'),
+    sys.stdout.flush()
+
+    req_fig = plt.figure()
+    req_ax = req_fig.add_subplot(111)
+
+    req_ax.plot(requested, label='requested memory', rasterized=True)
+    req_ax.plot(allocated, label='allocated memory', rasterized=True)
+
+    req_ax.set_xticks([])
+    req_ax.set_xlabel('Application timeline')
+
+    req_ax.yaxis.set_major_formatter(FuncFormatter(megabytes))
+    req_ax.get_yaxis().tick_left()
+    
+    req_ax.legend(bbox_to_anchor=(0, 1.02, 1., .102), loc=3, ncol=2,
+            mode="expand", borderaxespad=0.)
+
+    req_fig.savefig('{}_mem_usage.pdf'.format(arg1), dpi=150)
+    print('Done.')
+    # Memory usage - END
+
+    return 0
+
+if __name__=='__main__':
+    if len(sys.argv) < 2:
+        sys.exit('Usage: %s trace-file' % sys.argv[0])
+    if not os.path.exists(sys.argv[1]):
+        sys.exit('ERROR: Trace file %s was not found!' % sys.argv[1])
+    sys.exit(main(sys.argv[1]))