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