summaryrefslogtreecommitdiff
path: root/nv-report.py
blob: b97f4a1d38ecc1eacaa6c5776da3a43339f48881 (plain)
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
#!/usr/bin/python

"""
We're matching lines like

5.shader_test - type: 1, local: 0, gpr: 4, inst: 7, bytes: 56
11.shader_test - type: 1, local: 0, gpr: 4, inst: 1, bytes: 8
"""

import re
import sys

class Stat(object):

    def __init__(self, m=None):
        if m:
            self.local = int(m.group("local"), 10)
            self.gpr = int(m.group("gpr"), 10)
            self.inst = int(m.group("inst"), 10)
            self.bytes = int(m.group("bytes"), 10)
        else:
            self.local = 0
            self.gpr = 0
            self.inst = 0
            self.bytes = 0

    def __eq__(self, other):
        return (self.local == other.local and
                self.gpr == other.gpr and
                self.inst == other.inst and
                self.bytes == other.bytes)

class Stats(object):

    def __init__(self):
        self.stats = {}
        self.local = 0
        self.gpr = 0
        self.inst = 0
        self.bytes = 0

    def record(self, name, stat):
        assert name not in self.stats, name
        self.stats[name] = stat
        for attr in ("local", "gpr", "inst", "bytes"):
            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+)$")

def analyze(fname):
    stats = Stats()
    with open(fname, "r") as f:
        for line in f.xreadlines():
            if line.startswith("Thread "):
                continue
            m = RE.match(line)
            assert m, line
            stats.record(m.group("name") + " - " + m.group("type"), Stat(m))

    return stats

def diff(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:
        a = after.stats[key]
        b = before.stats[key]
        if a != b:
            for attr in ("local", "gpr", "inst", "bytes"):
                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.inst, after.inst)
    print "total gprs used in shared programs    :", diff(before.gpr, after.gpr)
    print "total local used in shared programs   :", diff(before.local, after.local)
    print
    print "%10s %10s %10s %10s %10s " % ("", "local", "gpr", "inst", "bytes")
    print "%10s " % "helped",
    for attr in ("local", "gpr", "inst", "bytes"):
        print "%10d " % getattr(helped, attr),
    print
    print "%10s " % "hurt",
    for attr in ("local", "gpr", "inst", "bytes"):
        print "%10d " % getattr(hurt, attr),


if __name__ == "__main__":
    main(sys.argv)