stats.py revision 1318
1#!/usr/bin/env python 2from __future__ import division 3import re, sys, math 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 259 print "%s:" % stat.name 260 print "%-30s %12s %12s %4s %5s %5s %5s" % \ 261 ("run name", "average", "stdev", ">10%", ">1SDV", ">2SDV", "SAMP") 262 print "%-30s %12s %12s %4s %5s %5s %5s" % \ 263 ("------------------------------", "------------", 264 "------------", "----", "-----", "-----", "-----") 265 #loop through all the selected runs 266 for run in runs: 267 info.display_run = run.run; 268 runTicks = info.source.retTicks([ run ]) 269 #throw away the first one, it's 0 270 runTicks.pop(0) 271 stat.ticks = runTicks 272 avg = float(stat) 273 stdev = 0 274 numoutsideavg = 0 275 numoutside1std = 0 276 numoutside2std = 0 277 278 #loop through all the various ticks for each run 279 for tick in runTicks: 280 stat.ticks = str(tick) 281 val = float(stat) 282 if (val < (avg * .9)) or (val > (avg * 1.1)): 283 numoutsideavg += 1 284 stdev += pow((val-avg),2) 285 286 stdev = math.sqrt(stdev / len(runTicks)) 287 for tick in runTicks: 288 stat.ticks = str(tick) 289 val = float(stat) 290 if (val < (avg - stdev)) or (val > (avg + stdev)): 291 numoutside1std += 1 292 if (val < (avg - (2*stdev))) or (val > (avg + (2*stdev))): 293 numoutside2std += 1 294 295 print "%-30s %12s %12s %4s %5s %5s %5s" % \ 296 (run.name, "%.1f" % avg, "%.1f" % stdev, 297 "%d" % numoutsideavg, "%d" % numoutside1std, 298 "%d" % numoutside2std, "%d" % len(runTicks)) 299 return 300 301 302 if command == 'stats': 303 if len(args) == 0: 304 info.source.listStats() 305 elif len(args) == 1: 306 info.source.listStats(args[0]) 307 else: 308 raise CommandException 309 310 return 311 312 if command == 'stat': 313 if len(args) != 1: 314 raise CommandException 315 316 stats = info.source.getStat(args[0]) 317 for stat in stats: 318 if options.graph: 319 graphdata(runs, options, stat.name, stat.name, stat) 320 else: 321 if options.ticks: 322 print 'only displaying sample %s' % options.ticks 323 stat.ticks = options.ticks 324 325 if options.binned: 326 print 'kernel ticks' 327 stat.bins = 'kernel' 328 printdata(runs, stat) 329 330 print 'idle ticks' 331 stat.bins = 'idle' 332 printdata(runs, stat) 333 334 print 'user ticks' 335 stat.bins = 'user' 336 printdata(runs, stat) 337 338 print 'interrupt ticks' 339 stat.bins = 'interrupt' 340 printdata(runs, stat) 341 342 print 'total ticks' 343 344 stat.bins = None 345 print stat.name 346 printdata(runs, stat) 347 return 348 349 if command == 'formula': 350 if len(args) != 1: 351 raise CommandException 352 353 stats = eval(args[0]) 354 for stat in stats: 355 if options.graph: 356 graphdata(runs, options, stat.name, stat.name, stat) 357 else: 358 if options.binned: 359 print 'kernel ticks' 360 stat.bins = 'kernel' 361 printdata(runs, stat) 362 363 print 'idle ticks' 364 stat.bins = 'idle' 365 printdata(runs, stat) 366 367 print 'user ticks' 368 stat.bins = 'user' 369 printdata(runs, stat) 370 371 print 'interrupt ticks' 372 stat.bins = 'interrupt' 373 printdata(runs, stat) 374 375 print 'total ticks' 376 377 stat.bins = None 378 print args[0] 379 printdata(runs, stat) 380 return 381 382 if command == 'bins': 383 if len(args) == 0: 384 info.source.listBins() 385 elif len(args) == 1: 386 info.source.listBins(args[0]) 387 else: 388 raise CommandException 389 390 return 391 392 if command == 'formulas': 393 if len(args) == 0: 394 info.source.listFormulas() 395 elif len(args) == 1: 396 info.source.listFormulas(args[0]) 397 else: 398 raise CommandException 399 400 return 401 402 if command == 'samples': 403 if len(args): 404 raise CommandException 405 406 info.source.listTicks(runs) 407 return 408 409 if len(args): 410 raise CommandException 411 412 system = info.source.__dict__[options.system] 413 414 if command == 'usertime': 415 import copy 416 kernel = copy.copy(system.full_cpu.numCycles) 417 kernel.bins = 'kernel' 418 419 user = copy.copy(system.full_cpu.numCycles) 420 user.bins = 'user' 421 422 if options.graph: 423 graphdata(runs, options, 'usertime', 'User Fraction', 424 user / system.full_cpu.numCycles) 425 else: 426 printdata(runs, user / system.full_cpu.numCycles) 427 return 428 429 if command == 'ticks': 430 if options.binned: 431 print 'kernel ticks' 432 system.full_cpu.numCycles.bins = 'kernel' 433 printdata(runs, system.full_cpu.numCycles) 434 435 print 'idle ticks' 436 system.full_cpu.numCycles.bins = 'idle' 437 printdata(runs, system.full_cpu.numCycles) 438 439 print 'user ticks' 440 system.full_cpu.numCycles.bins = 'user' 441 printdata(runs, system.full_cpu.numCycles) 442 443 print 'total ticks' 444 445 system.full_cpu.numCycles.bins = None 446 printdata(runs, system.full_cpu.numCycles) 447 return 448 449 if command == 'packets': 450 packets = system.tsunami.etherdev.rxPackets 451 if options.graph: 452 graphdata(runs, options, 'packets', 'Packets', packets) 453 else: 454 printdata(runs, packets) 455 return 456 457 if command == 'ppt' or command == 'tpp': 458 ppt = system.tsunami.etherdev.rxPackets / sim_ticks 459 printdata(runs, ppt, command == 'tpp') 460 return 461 462 if command == 'pps': 463 pps = system.tsunami.etherdev.rxPackets / sim_seconds 464 if options.graph: 465 graphdata(runs, options, 'pps', 'Packets/s', pps) 466 else: 467 printdata(runs, pps) 468 return 469 470 if command == 'bpt' or command == 'tpb': 471 bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes 472 bpt = bytes / sim_ticks * 8 473 if options.graph: 474 graphdata(runs, options, 'bpt', 'bps / Hz', bpt) 475 else: 476 printdata(runs, bpt, command == 'tpb') 477 return 478 479 if command == 'bptb' or command == 'tpbb': 480 bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes 481 482 print 'kernel stats' 483 bytes.bins = 'kernel' 484 printdata(runs, bytes / ticks) 485 486 print 'idle stats' 487 bytes.bins = 'idle' 488 printdata(runs, bytes / ticks) 489 490 print 'user stats' 491 bytes.bins = 'user' 492 printdata(runs, bytes / ticks) 493 494 return 495 496 if command == 'bytes': 497 stat = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes 498 499 if options.binned: 500 print '%s kernel stats' % stat.name 501 stat.bins = 'kernel' 502 printdata(runs, stat) 503 504 print '%s idle stats' % stat.name 505 stat.bins = 'idle' 506 printdata(runs, stat) 507 508 print '%s user stats' % stat.name 509 stat.bins = 'user' 510 printdata(runs, stat) 511 512 print '%s total stats' % stat.name 513 stat.bins = None 514 515 printdata(runs, stat) 516 return 517 518 if command == 'rxbps': 519 gbps = system.tsunami.etherdev.rxBandwidth / 1e9 520 if options.graph: 521 graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)', gbps) 522 else: 523 printdata(runs, gbps) 524 return 525 526 if command == 'txbps': 527 gbps = system.tsunami.etherdev.txBandwidth / 1e9 528 if options.graph: 529 graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)', gbps) 530 else: 531 printdata(runs, gbps) 532 return 533 534 if command == 'bps': 535 rxbps = system.tsunami.etherdev.rxBandwidth 536 txbps = system.tsunami.etherdev.txBandwidth 537 gbps = (rxbps + txbps) / 1e9 538 if options.graph: 539 graphdata(runs, options, 'bps', 'Bandwidth (Gbps)', gbps) 540 else: 541 printdata(runs, gbps) 542 return 543 544 if command == 'misses': 545 stat = system.L2.overall_mshr_misses 546 if options.binned: 547 print '%s kernel stats' % stat.name 548 stat.bins = 'kernel' 549 printdata(runs, stat) 550 551 print '%s idle stats' % stat.name 552 stat.bins = 'idle' 553 printdata(runs, stat) 554 555 print '%s user stats' % stat.name 556 stat.bins = 'user' 557 printdata(runs, stat) 558 559 print '%s total stats' % stat.name 560 561 stat.bins = None 562 if options.graph: 563 graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat) 564 else: 565 printdata(runs, stat) 566 return 567 568 if command == 'mpkb': 569 misses = system.L2.overall_mshr_misses 570 rxbytes = system.tsunami.etherdev.rxBytes 571 txbytes = system.tsunami.etherdev.txBytes 572 573 if options.binned: 574 print 'mpkb kernel stats' 575 misses.bins = 'kernel' 576 mpkb = misses / ((rxbytes + txbytes) / 1024) 577 printdata(runs, mpkb) 578 579 print 'mpkb idle stats' 580 misses.bins = 'idle' 581 mpkb = misses / ((rxbytes + txbytes) / 1024) 582 printdata(runs, mpkb) 583 584 print 'mpkb user stats' 585 misses.bins = 'user' 586 mpkb = misses / ((rxbytes + txbytes) / 1024) 587 printdata(runs, mpkb) 588 589 print 'mpkb total stats' 590 591 mpkb = misses / ((rxbytes + txbytes) / 1024) 592 misses.bins = None 593 if options.graph: 594 graphdata(runs, options, 'mpkb', 'Misses / KB', mpkb) 595 else: 596 printdata(runs, mpkb) 597 return 598 599 if command == 'ipkb': 600 interrupts = system.full_cpu.kern.faults[4] 601 rxbytes = system.tsunami.etherdev.rxBytes 602 txbytes = system.tsunami.etherdev.txBytes 603 604 if options.binned: 605 print 'ipkb kernel stats' 606 interrupts.bins = 'kernel' 607 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 608 printdata(runs, ipkb) 609 610 print 'ipkb idle stats' 611 interrupts.bins = 'idle' 612 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 613 printdata(runs, ipkb) 614 615 print 'ipkb user stats' 616 interrupts.bins = 'user' 617 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 618 printdata(runs, ipkb) 619 620 print 'ipkb total stats' 621 622 ipkb = interrupts / ((rxbytes + txbytes) / 1024) 623 interrupts.bins = None 624 if options.graph: 625 graphdata(runs, options, 'ipkb', 'Interrupts / KB', ipkb) 626 else: 627 printdata(runs, ipkb) 628 return 629 630 if command == 'execute': 631 printdata(runs, system.full_cpu.ISSUE__count) 632 return 633 634 if command == 'commit': 635 printdata(runs, system.full_cpu.COM__count) 636 return 637 638 if command == 'fetch': 639 printdata(runs, system.full_cpu.FETCH__count) 640 return 641 642 if command == 'bpp': 643 ed = system.tsunami.etherdev 644 bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets) 645 if options.graph: 646 graphdata(runs, options, 'bpp', 'Bytes / Packet', bpp) 647 else: 648 printdata(runs, bpp) 649 return 650 651 if command == 'rxbpp': 652 bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets 653 if options.graph: 654 graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet', bpp) 655 else: 656 printdata(runs, bpp) 657 return 658 659 if command == 'txbpp': 660 bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets 661 if options.graph: 662 graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet', bpp) 663 else: 664 printdata(runs, bpp) 665 return 666 667 if command == 'rtp': 668 rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets 669 if options.graph: 670 graphdata(runs, options, 'rtp', 'rxPackets / txPackets', rtp) 671 else: 672 printdata(runs, rtp) 673 return 674 675 if command == 'rtb': 676 rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes 677 if options.graph: 678 graphdata(runs, options, 'rtb', 'rxBytes / txBytes', rtb) 679 else: 680 printdata(runs, rtb) 681 return 682 683 raise CommandException 684 685 686class Options: pass 687 688if __name__ == '__main__': 689 import getpass 690 691 options = Options() 692 options.host = 'zizzer.pool' 693 options.db = None 694 options.passwd = '' 695 options.user = getpass.getuser() 696 options.runs = None 697 options.system = 'client' 698 options.get = None 699 options.binned = False 700 options.graph = False 701 options.graph68 = False 702 options.ticks = False 703 704 opts, args = getopts(sys.argv[1:], '-6BEFGd:g:h:pr:s:u:T:') 705 for o,a in opts: 706 if o == '-6': 707 options.graph68 = True 708 if o == '-B': 709 options.binned = True 710 if o == '-E': 711 printval.mode = 'E' 712 if o == '-F': 713 printval.mode = 'F' 714 if o == '-G': 715 options.graph = True; 716 if o == '-d': 717 options.db = a 718 if o == '-g': 719 options.get = a 720 if o == '-h': 721 options.host = a 722 if o == '-p': 723 options.passwd = getpass.getpass() 724 if o == '-r': 725 options.runs = a 726 if o == '-u': 727 options.user = a 728 if o == '-s': 729 options.system = a 730 if o == '-T': 731 options.ticks = a 732 733 if len(args) == 0: 734 usage() 735 736 command = args[0] 737 args = args[1:] 738 739 try: 740 commands(options, command, args) 741 except CommandException: 742 usage() 743