1#!/usr/bin/env python 2 3"""Plot the performance for different block sizes of one function across 4variants. 5""" 6 7import libplot 8 9import pylab 10import pdb 11import math 12 13def pretty_kb(v): 14 if v < 1024: 15 return '%d' % v 16 else: 17 if v % 1024 == 0: 18 return '%d k' % (v//1024) 19 else: 20 return '%.1f k' % (v/1024) 21 22def plot(records, function, alignment=None, scale=1): 23 variants = libplot.unique(records, 'variant', prefer='this') 24 records = [x for x in records if x.function==function] 25 26 if alignment != None: 27 records = [x for x in records if x.src_alignment==alignment[0] and 28 x.dst_alignment==alignment[1]] 29 30 alignments = libplot.unique(records, ('src_alignment', 'dst_alignment')) 31 if len(alignments) != 1: 32 return False 33 if libplot.alignments_equal(alignments): 34 aalignment = alignments[0][0] 35 else: 36 aalignment = "%s:%s" % (alignments[0][0], alignments[0][1]) 37 38 bytes = libplot.unique(records, 'bytes')[0] 39 40 colours = libplot.make_colours() 41 all_x = [] 42 43 pylab.figure(1).set_size_inches((6.4*scale, 4.8*scale)) 44 pylab.clf() 45 46 if 'str' in function: 47 # The harness fills out to 16k. Anything past that is an 48 # early match 49 top = 16384 50 else: 51 top = 2**31 52 53 for variant in variants: 54 matches = [x for x in records if x.variant==variant and x.bytes <= top] 55 matches.sort(key=lambda x: x.bytes) 56 57 X = sorted(list(set([x.bytes for x in matches]))) 58 Y = [] 59 Yerr = [] 60 for xbytes in X: 61 vals = [x.bytes*x.loops/x.elapsed/(1024*1024) for x in matches if x.bytes == xbytes] 62 if len(vals) > 1: 63 mean = sum(vals)/len(vals) 64 Y.append(mean) 65 if len(Yerr) == 0: 66 Yerr = [[], []] 67 err1 = max(vals) - mean 68 assert err1 >= 0 69 err2 = min(vals) - mean 70 assert err2 <= 0 71 Yerr[0].append(abs(err2)) 72 Yerr[1].append(err1) 73 else: 74 Y.append(vals[0]) 75 76 all_x.extend(X) 77 colour = colours.next() 78 79 if X: 80 pylab.plot(X, Y, c=colour) 81 if len(Yerr) > 0: 82 pylab.errorbar(X, Y, yerr=Yerr, c=colour, label=variant, fmt='o') 83 else: 84 pylab.scatter(X, Y, c=colour, label=variant, edgecolors='none') 85 86 pylab.legend(loc='upper left', ncol=3, prop={'size': 'small'}) 87 pylab.grid() 88 pylab.title('%(function)s of %(aalignment)s byte aligned blocks' % locals()) 89 pylab.xlabel('Size (B)') 90 pylab.ylabel('Rate (MB/s)') 91 92 # Figure out how high the range goes 93 top = max(all_x) 94 95 power = int(round(math.log(max(all_x)) / math.log(2))) 96 97 pylab.semilogx() 98 99 pylab.axes().set_xticks([2**x for x in range(0, power+1)]) 100 pylab.axes().set_xticklabels([pretty_kb(2**x) for x in range(0, power+1)]) 101 pylab.xlim(0, top) 102 pylab.ylim(0, pylab.ylim()[1]) 103 return True 104 105def main(): 106 records = libplot.parse() 107 108 functions = libplot.unique(records, 'function') 109 alignments = libplot.unique(records, ('src_alignment', 'dst_alignment')) 110 111 for function in functions: 112 for alignment in alignments: 113 for scale in [1, 2.5]: 114 if plot(records, function, alignment, scale): 115 pylab.savefig('sizes-%s-%02d-%02d-%.1f.png' % (function, alignment[0], alignment[1], scale), dpi=72) 116 117 pylab.show() 118 119if __name__ == '__main__': 120 main() 121