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