]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/cortex-strings/scripts/plot-sizes.py
MFV: r329072
[FreeBSD/FreeBSD.git] / contrib / cortex-strings / scripts / plot-sizes.py
1 #!/usr/bin/env python
2
3 """Plot the performance for different block sizes of one function across
4 variants.
5 """
6
7 import libplot
8
9 import pylab
10 import pdb
11 import math
12
13 def 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
22 def 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
105 def 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
119 if __name__ == '__main__':
120     main()