1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#!/usr/bin/python
"""
We're matching groups of lines like
SHADER-DB: FRAG prog 22/1: 16 instructions, 32 dwords
SHADER-DB: FRAG prog 22/1: 0 half, 6 full
SHADER-DB: FRAG prog 22/1: 0 const, 0 constlen
"""
import re
import sys
class Stat(object):
def __init__(self, m=None):
if m:
self.half = int(m.group("half"), 10)
self.full = int(m.group("full"), 10)
self.const = int(m.group("const"), 10)
self.instr = int(m.group("instr"), 10)
self.dwords = int(m.group("dwords"), 10)
else:
self.half = 0
self.full = 0
self.const = 0
self.instr = 0
self.dwords = 0
def __eq__(self, other):
return (self.half == other.half and
self.full == other.full and
self.const == other.const and
self.instr == other.instr and
self.dwords == other.dwords)
class Stats(object):
def __init__(self):
self.stats = {}
self.half = 0
self.full = 0
self.const = 0
self.instr = 0
self.dwords = 0
def record(self, name, stat):
assert name not in self.stats, name
self.stats[name] = stat
for attr in ("half", "full", "const", "instr", "dwords"):
setattr(self, attr, getattr(self, attr) + getattr(stat, attr))
#RE = re.compile(r"^(?P<name>.*) - type: (?P<type>\d+), local: (?P<local>\d+), "
# r"gpr: (?P<gpr>\d+), inst: (?P<inst>\d+), "
# r"bytes: (?P<bytes>\d+)$")
#SHADER-DB: FRAG prog 22/1: 16 instructions, 32 dwords
#SHADER-DB: FRAG prog 22/1: 0 half, 6 full
#SHADER-DB: FRAG prog 22/1: 0 const, 0 constlen
RE1 = re.compile(r"^SHADER-DB: (?P<name>[A-Z]+ prog \d+/\d+): (?P<line>.*)$")
RE2 = re.compile(r"^(?P<instr>\d+) instructions, (?P<dwords>\d+) dwords, (?P<half>\d+) half, (?P<full>\d+) full, (?P<const>\d+) const, \d+ constlen$")
def analyze(fname):
stats = Stats()
with open(fname, "r") as f:
i = 0
str = None
for line in f.xreadlines():
m1 = RE1.match(line)
if m1:
l = m1.group("line")
if str:
str = str + ", " + l
else:
str = l
i = i + 1
if i == 3:
#print(m1.group("name") + ": " + str)
m2 = RE2.match(str)
assert m2, str
stats.record(m1.group("name"), Stat(m2))
i = 0
str = None
return stats
def diff(a, b):
if a == 0:
return "%d -> %d" % (a, b)
return "%d -> %d (%.2f%%)" % (a, b, b * 100. / a - 100.)
def main(argv):
# Count up each of the metrics in the before and after, and
# produce hurt/helped comparisons.
before = analyze(argv[1])
after = analyze(argv[2])
keys = before.stats.keys()
assert after.stats.keys() == keys
helped = Stat()
hurt = Stat()
for key in keys:
if not key in after.stats and key in before.stats:
continue
a = after.stats[key]
b = before.stats[key]
if a != b:
for attr in ("half", "full", "const", "instr", "dwords"):
aa = getattr(a, attr)
ba = getattr(b, attr)
if aa == ba:
continue
if aa < ba:
setattr(helped, attr,
getattr(helped, attr) + 1)
else:
setattr(hurt, attr,
getattr(hurt, attr) + 1)
print "total instructions in shared programs: ", diff(before.instr, after.instr)
print "total dwords in shared programs: ", diff(before.dwords, after.dwords)
print "total full registers used in shared programs: ", diff(before.full, after.full)
print "total half registers used in shader programs: ", diff(before.half, after.half)
print "total const registers used in shared programs: ", diff(before.const, after.const)
print
print "%10s %10s %10s %10s %10s %10s" % ("", "half", "full", "const", "instr", "dwords")
print "%10s " % "helped",
for attr in ("half", "full", "const", "instr", "dwords"):
print "%10d " % getattr(helped, attr),
print
print "%10s " % "hurt",
for attr in ("half", "full", "const", "instr", "dwords"):
print "%10d " % getattr(hurt, attr),
if __name__ == "__main__":
main(sys.argv)
|