stats.py revision 1309
1#!/usr/bin/env python
2from __future__ import division
3import re, sys
4
5def usage():
6    print '''\
7Usage: %s [-E] [-F] [-d <db> ] [-g <get> ] [-h <host>] [-p]
8       [-s <system>] [-r <runs> ] [-u <username>] <command> [command args]
9''' % sys.argv[0]
10    sys.exit(1)
11
12def getopts(list, flags):
13    import getopt
14    try:
15        opts, args = getopt.getopt(list, flags)
16    except getopt.GetoptError:
17        usage()
18
19    return opts, args
20
21def printval(name, value, invert = False):
22    if invert and value != 0.0:
23        value = 1 / value
24
25    if value == (1e300*1e300):
26        return
27
28    if printval.mode == 'G':
29        print '%s:    %g' % (name, value)
30    elif printval.mode != 'F' and value > 1e6:
31        print '%s:    %0.5e' % (name, value)
32    else:
33        print '%s:    %f' % (name, value)
34
35printval.mode = 'G'
36
37def unique(list):
38    set = {}
39    map(set.__setitem__, list, [])
40    return set.keys()
41
42def graphdata68(runs, options, tag, label, value):
43    import info
44    configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
45    benchmarks = [ 'm', 's', 'snt', 'nb1', 'w1', 'w2', 'w3', 'w4', 'nm', 'ns', 'nw1', 'nw2', 'nw3' ]
46    dmas = [ 'x' ]
47    caches = [ '2', '4' ]
48
49    names = []
50
51    bench_system = {
52        'm' : 'client',
53        's' : 'client',
54        'snt' : 'client',
55        'nb1' : 'server',
56        'nb2' : 'server',
57        'nt1' : 'server',
58        'nt2' : 'server',
59        'w1' : 'server',
60        'w2' : 'server',
61        'w3' : 'server',
62        'w4' : 'server',
63        'w1s' : 'server',
64        'w2s' : 'server',
65        'w3s' : 'server',
66        'ns' : 'natbox',
67        'nm' : 'natbox',
68        'nw1' : 'natbox',
69        'nw2' : 'natbox',
70        'nw3' : 'natbox'
71        }
72
73    for bench in benchmarks:
74        if bench_system[bench] != options.system:
75            continue
76
77        for dma in dmas:
78            for cache in caches:
79                    names.append([bench, dma, cache])
80
81    for bench,dma,cache in names:
82        base = '%s.%s.%s' % (bench, dma, cache)
83        fname = 'data/%s.%s.68.dat' % (tag, base)
84        f = open(fname, 'w')
85        print >>f, '#set TITLE = '
86        print >>f, '#set ylbl = %s' % label
87        #print >>f, '#set sublabels = %s' % ' '.join(configs)
88        print >>f, '#set sublabels = ste hte htd ocm occ ocs'
89
90        for speed,freq in zip(['s', '6', '8', 'q'],['4GHz', '6GHz','8GHz', '10GHz']):
91            print >>f, '"%s"' % freq,
92            for conf in configs:
93                name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
94                run = info.source.allRunNames[name]
95                info.display_run = run.run;
96                val = float(value)
97                if val == 1e300*1e300:
98                    print >>f, 0.0,
99                else:
100                    print >>f, "%f" % val,
101            print >>f
102        f.close()
103
104def graphdata(runs, options, tag, label, value):
105    if options.graph68:
106        graphdata68(runs, options, tag, label, value)
107        return
108
109    import info
110    configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
111    #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ]
112    #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'w1', 'w2', 'w3', 'ns', 'nm', 'w1s' ]
113    benchmarks = [ 'm', 's', 'nb1', 'nb2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'snt' ]
114    #dmas = [ 'x', 'd', 'b' ]
115    dmas = [ 'x' ]
116    caches = [ '2', '4' ]
117
118    names = []
119
120    bench_system = {
121        'm' : 'client',
122        's' : 'client',
123        'snt' : 'client',
124        'nb1' : 'server',
125        'nb2' : 'server',
126        'nt1' : 'server',
127        'nt2' : 'server',
128        'w1' : 'server',
129        'w2' : 'server',
130        'w3' : 'server',
131        'w4' : 'server',
132        'w1s' : 'server',
133        'w2s' : 'server',
134        'w3s' : 'server',
135        'ns' : 'natbox',
136        'nm' : 'natbox',
137        'nw1' : 'natbox',
138        'nw2' : 'natbox',
139        'nw3' : 'natbox'
140        }
141
142    for bench in benchmarks:
143        if bench_system[bench] != options.system:
144            continue
145
146        for dma in dmas:
147            for cache in caches:
148                    names.append([bench, dma, cache])
149
150    for bench,dma,cache in names:
151        base = '%s.%s.%s' % (bench, dma, cache)
152        fname = 'data/%s.%s.dat' % (tag, base)
153        f = open(fname, 'w')
154        print >>f, '#set TITLE = '
155        print >>f, '#set ylbl = %s' % label
156        #print >>f, '#set sublabels = %s' % ' '.join(configs)
157        print >>f, '#set sublabels = ste hte htd ocm occ ocs'
158
159        for speed,freq in zip(['s', 'q'],['4GHz','10GHz']):
160            print >>f, '"%s"' % freq,
161            for conf in configs:
162                name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
163                run = info.source.allRunNames[name]
164                info.display_run = run.run;
165                val = float(value)
166                if val == 1e300*1e300:
167                    print >>f, 0.0,
168                else:
169                    print >>f, "%f" % val,
170            print >>f
171        f.close()
172
173def printdata(runs, value, invert = False):
174    import info
175    for run in runs:
176        info.display_run = run.run;
177        val = float(value)
178        printval(run.name, val)
179
180class CommandException(Exception):
181    pass
182
183def commands(options, command, args):
184    if command == 'database':
185        if len(args) == 0: raise CommandException
186
187        import dbinit
188        mydb = dbinit.MyDB(options)
189
190        if args[0] == 'drop':
191            if len(args) > 2: raise CommandException
192            mydb.admin()
193            mydb.drop()
194            if len(args) == 2 and args[1] == 'init':
195                mydb.create()
196                mydb.connect()
197                mydb.populate()
198            mydb.close()
199            return
200
201        if args[0] == 'init':
202            if len(args) > 1: raise CommandException
203            mydb.admin()
204            mydb.create()
205            mydb.connect()
206            mydb.populate()
207            mydb.close()
208            return
209
210        if args[0] == 'clean':
211            if len(args) > 1: raise CommandException
212            mydb.connect()
213            mydb.clean()
214            return
215
216        raise CommandException
217
218    import db, info
219    info.source = db.Database()
220    info.source.host = options.host
221    info.source.db = options.db
222    info.source.passwd = options.passwd
223    info.source.user = options.user
224    info.source.connect()
225    info.source.update_dict(globals())
226
227    if type(options.get) is str:
228        info.source.get = options.get
229
230    if options.runs is None:
231        runs = info.source.allRuns
232    else:
233        rx = re.compile(options.runs)
234        runs = []
235        for run in info.source.allRuns:
236            if rx.match(run.name):
237                runs.append(run)
238
239    info.display_run = runs[0].run
240
241    if command == 'runs':
242        user = None
243        opts, args = getopts(args, '-u')
244        if len(args):
245            raise CommandException
246        for o,a in opts:
247            if o == '-u':
248                user = a
249        info.source.listRuns(user)
250        return
251
252    if command == 'stability':
253        stats = info.source.getStat(args[0])
254        info.source.get = "avg"
255
256        #loop through all the stats selected
257        for stat in stats:
258            avg = float(stat)
259
260            #loop through all the selected runs
261            for run in runs:
262                info.display_run = run.run;
263                #print run.name
264                #print avg
265                runTicks = info.source.retTicks([ run ])
266                #throw away the first one, it's 0
267                runTicks.pop(0)
268
269                #loop through all the various ticks for each run
270                for tick in runTicks:
271                    stat.ticks = str(tick)
272                    val = float(stat)
273                    if (val < (avg * .9)) or (val > (avg * 1.1)):
274                        print '%s:%s is %f, which is more than 10%% of the'\
275                              'mean %f' % (run.name, stat.name, stat, avg)
276
277
278
279
280        return
281
282
283    if command == 'stats':
284        if len(args) == 0:
285            info.source.listStats()
286        elif len(args) == 1:
287            info.source.listStats(args[0])
288        else:
289            raise CommandException
290
291        return
292
293    if command == 'stat':
294        if len(args) != 1:
295            raise CommandException
296
297        stats = info.source.getStat(args[0])
298        for stat in stats:
299            if options.graph:
300                graphdata(runs, options, stat.name, stat.name, stat)
301            else:
302                if options.ticks:
303                   print 'only displaying sample %s' % options.ticks
304                   stat.ticks = options.ticks
305
306                if options.binned:
307                    print 'kernel ticks'
308                    stat.bins = 'kernel'
309                    printdata(runs, stat)
310
311                    print 'idle ticks'
312                    stat.bins = 'idle'
313                    printdata(runs, stat)
314
315                    print 'user ticks'
316                    stat.bins = 'user'
317                    printdata(runs, stat)
318
319                    print 'interrupt ticks'
320                    stat.bins = 'interrupt'
321                    printdata(runs, stat)
322
323                    print 'total ticks'
324
325                stat.bins = None
326                print stat.name
327                printdata(runs, stat)
328        return
329
330    if command == 'formula':
331        if len(args) != 1:
332            raise CommandException
333
334        stats = eval(args[0])
335        for stat in stats:
336            if options.graph:
337                graphdata(runs, options, stat.name, stat.name, stat)
338            else:
339                if options.binned:
340                    print 'kernel ticks'
341                    stat.bins = 'kernel'
342                    printdata(runs, stat)
343
344                    print 'idle ticks'
345                    stat.bins = 'idle'
346                    printdata(runs, stat)
347
348                    print 'user ticks'
349                    stat.bins = 'user'
350                    printdata(runs, stat)
351
352                    print 'interrupt ticks'
353                    stat.bins = 'interrupt'
354                    printdata(runs, stat)
355
356                    print 'total ticks'
357
358                stat.bins = None
359                print args[0]
360                printdata(runs, stat)
361        return
362
363    if command == 'bins':
364        if len(args) == 0:
365            info.source.listBins()
366        elif len(args) == 1:
367            info.source.listBins(args[0])
368        else:
369            raise CommandException
370
371        return
372
373    if command == 'formulas':
374        if len(args) == 0:
375            info.source.listFormulas()
376        elif len(args) == 1:
377            info.source.listFormulas(args[0])
378        else:
379            raise CommandException
380
381        return
382
383    if command == 'samples':
384        if len(args):
385            raise CommandException
386
387        info.source.listTicks(runs)
388        return
389
390    if len(args):
391        raise CommandException
392
393    system = info.source.__dict__[options.system]
394
395    if command == 'usertime':
396        import copy
397        kernel = copy.copy(system.full_cpu.numCycles)
398        kernel.bins = 'kernel'
399
400        user = copy.copy(system.full_cpu.numCycles)
401        user.bins = 'user'
402
403        if options.graph:
404            graphdata(runs, options, 'usertime', 'User Fraction',
405                      user / system.full_cpu.numCycles)
406        else:
407            printdata(runs, user / system.full_cpu.numCycles)
408        return
409
410    if command == 'ticks':
411        if options.binned:
412            print 'kernel ticks'
413            system.full_cpu.numCycles.bins = 'kernel'
414            printdata(runs, system.full_cpu.numCycles)
415
416            print 'idle ticks'
417            system.full_cpu.numCycles.bins = 'idle'
418            printdata(runs, system.full_cpu.numCycles)
419
420            print 'user ticks'
421            system.full_cpu.numCycles.bins = 'user'
422            printdata(runs, system.full_cpu.numCycles)
423
424            print 'total ticks'
425
426        system.full_cpu.numCycles.bins = None
427        printdata(runs, system.full_cpu.numCycles)
428        return
429
430    if command == 'packets':
431        packets = system.tsunami.etherdev.rxPackets
432        if options.graph:
433            graphdata(runs, options, 'packets', 'Packets', packets)
434        else:
435            printdata(runs, packets)
436        return
437
438    if command == 'ppt' or command == 'tpp':
439        ppt = system.tsunami.etherdev.rxPackets / sim_ticks
440        printdata(runs, ppt, command == 'tpp')
441        return
442
443    if command == 'pps':
444        pps = system.tsunami.etherdev.rxPackets / sim_seconds
445        if options.graph:
446            graphdata(runs, options, 'pps', 'Packets/s', pps)
447        else:
448            printdata(runs, pps)
449        return
450
451    if command == 'bpt' or command == 'tpb':
452        bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
453        bpt = bytes / sim_ticks * 8
454        if options.graph:
455            graphdata(runs, options, 'bpt', 'bps / Hz', bpt)
456        else:
457            printdata(runs, bpt, command == 'tpb')
458        return
459
460    if command == 'bptb' or command == 'tpbb':
461        bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
462
463        print 'kernel stats'
464        bytes.bins = 'kernel'
465        printdata(runs, bytes / ticks)
466
467        print 'idle stats'
468        bytes.bins = 'idle'
469        printdata(runs, bytes / ticks)
470
471        print 'user stats'
472        bytes.bins = 'user'
473        printdata(runs, bytes / ticks)
474
475        return
476
477    if command == 'bytes':
478        stat = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
479
480        if options.binned:
481            print '%s kernel stats' % stat.name
482            stat.bins = 'kernel'
483            printdata(runs, stat)
484
485            print '%s idle stats' % stat.name
486            stat.bins = 'idle'
487            printdata(runs, stat)
488
489            print '%s user stats' % stat.name
490            stat.bins = 'user'
491            printdata(runs, stat)
492
493            print '%s total stats' % stat.name
494            stat.bins = None
495
496        printdata(runs, stat)
497        return
498
499    if command == 'rxbps':
500        gbps = system.tsunami.etherdev.rxBandwidth / 1e9
501        if options.graph:
502            graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)',  gbps)
503        else:
504            printdata(runs, gbps)
505        return
506
507    if command == 'txbps':
508        gbps = system.tsunami.etherdev.txBandwidth / 1e9
509        if options.graph:
510            graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)',  gbps)
511        else:
512            printdata(runs, gbps)
513        return
514
515    if command == 'bps':
516        rxbps = system.tsunami.etherdev.rxBandwidth
517        txbps = system.tsunami.etherdev.txBandwidth
518        gbps = (rxbps + txbps) / 1e9
519        if options.graph:
520            graphdata(runs, options, 'bps', 'Bandwidth (Gbps)',  gbps)
521        else:
522            printdata(runs, gbps)
523        return
524
525    if command == 'misses':
526        stat = system.L2.overall_mshr_misses
527        if options.binned:
528            print '%s kernel stats' % stat.name
529            stat.bins = 'kernel'
530            printdata(runs, stat)
531
532            print '%s idle stats' % stat.name
533            stat.bins = 'idle'
534            printdata(runs, stat)
535
536            print '%s user stats' % stat.name
537            stat.bins = 'user'
538            printdata(runs, stat)
539
540            print '%s total stats' % stat.name
541
542        stat.bins = None
543        if options.graph:
544            graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat)
545        else:
546            printdata(runs, stat)
547        return
548
549    if command == 'mpkb':
550        misses = system.L2.overall_mshr_misses
551        rxbytes = system.tsunami.etherdev.rxBytes
552        txbytes = system.tsunami.etherdev.txBytes
553
554        if options.binned:
555            print 'mpkb kernel stats'
556            misses.bins = 'kernel'
557            mpkb = misses / ((rxbytes + txbytes) / 1024)
558            printdata(runs, mpkb)
559
560            print 'mpkb idle stats'
561            misses.bins = 'idle'
562            mpkb = misses / ((rxbytes + txbytes) / 1024)
563            printdata(runs, mpkb)
564
565            print 'mpkb user stats'
566            misses.bins = 'user'
567            mpkb = misses / ((rxbytes + txbytes) / 1024)
568            printdata(runs, mpkb)
569
570            print 'mpkb total stats'
571
572        mpkb = misses / ((rxbytes + txbytes) / 1024)
573        misses.bins = None
574        if options.graph:
575            graphdata(runs, options, 'mpkb', 'Misses / KB',  mpkb)
576        else:
577            printdata(runs, mpkb)
578        return
579
580    if command == 'ipkb':
581        interrupts = system.full_cpu.kern.faults[4]
582        rxbytes = system.tsunami.etherdev.rxBytes
583        txbytes = system.tsunami.etherdev.txBytes
584
585        if options.binned:
586            print 'ipkb kernel stats'
587            interrupts.bins = 'kernel'
588            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
589            printdata(runs, ipkb)
590
591            print 'ipkb idle stats'
592            interrupts.bins = 'idle'
593            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
594            printdata(runs, ipkb)
595
596            print 'ipkb user stats'
597            interrupts.bins = 'user'
598            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
599            printdata(runs, ipkb)
600
601            print 'ipkb total stats'
602
603        ipkb = interrupts / ((rxbytes + txbytes) / 1024)
604        interrupts.bins = None
605        if options.graph:
606            graphdata(runs, options, 'ipkb', 'Interrupts / KB',  ipkb)
607        else:
608            printdata(runs, ipkb)
609        return
610
611    if command == 'execute':
612        printdata(runs, system.full_cpu.ISSUE__count)
613        return
614
615    if command == 'commit':
616        printdata(runs, system.full_cpu.COM__count)
617        return
618
619    if command == 'fetch':
620        printdata(runs, system.full_cpu.FETCH__count)
621        return
622
623    if command == 'bpp':
624        ed = system.tsunami.etherdev
625        bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets)
626        if options.graph:
627            graphdata(runs, options, 'bpp', 'Bytes / Packet',  bpp)
628        else:
629            printdata(runs, bpp)
630        return
631
632    if command == 'rxbpp':
633        bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets
634        if options.graph:
635            graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet',  bpp)
636        else:
637            printdata(runs, bpp)
638        return
639
640    if command == 'txbpp':
641        bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets
642        if options.graph:
643            graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet',  bpp)
644        else:
645            printdata(runs, bpp)
646        return
647
648    if command == 'rtp':
649        rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets
650        if options.graph:
651            graphdata(runs, options, 'rtp', 'rxPackets / txPackets',  rtp)
652        else:
653            printdata(runs, rtp)
654        return
655
656    if command == 'rtb':
657        rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes
658        if options.graph:
659            graphdata(runs, options, 'rtb', 'rxBytes / txBytes',  rtb)
660        else:
661            printdata(runs, rtb)
662        return
663
664    raise CommandException
665
666
667class Options: pass
668
669if __name__ == '__main__':
670    import getpass
671
672    options = Options()
673    options.host = 'zizzer.pool'
674    options.db = None
675    options.passwd = ''
676    options.user = getpass.getuser()
677    options.runs = None
678    options.system = 'client'
679    options.get = None
680    options.binned = False
681    options.graph = False
682    options.graph68 = False
683    options.ticks = False
684
685    opts, args = getopts(sys.argv[1:], '-6BEFGd:g:h:pr:s:u:T:')
686    for o,a in opts:
687        if o == '-6':
688            options.graph68 = True
689        if o == '-B':
690            options.binned = True
691        if o == '-E':
692            printval.mode = 'E'
693        if o == '-F':
694            printval.mode = 'F'
695        if o == '-G':
696            options.graph = True;
697        if o == '-d':
698            options.db = a
699        if o == '-g':
700            options.get = a
701        if o == '-h':
702            options.host = a
703        if o == '-p':
704            options.passwd = getpass.getpass()
705        if o == '-r':
706            options.runs = a
707        if o == '-u':
708            options.user = a
709        if o == '-s':
710            options.system = a
711        if o == '-T':
712            options.ticks = a
713
714    if len(args) == 0:
715        usage()
716
717    command = args[0]
718    args = args[1:]
719
720    try:
721        commands(options, command, args)
722    except CommandException:
723        usage()
724